using private variable of a class

I wanted to know how to access my private variable.
I have written a small code snippet. Is it the right way of using private variable?

If not, can you please, let me know how to access a private variable of a class?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class nowords
{
        private:
            char string[];
        public:
            void nowords1(char *);         
};

void nowords :: nowrds1 (char string1[])
{
      //I want to take a input from keyboard and modify it as per requirement.

}
  int main(int argc, char** argv) {
    nowords nowordsnew; 
    nowordsnew.string2[]; // This throws me error
    nowordsnew.nowords1(string2);
    return 0;
}
No, it isn't the right way, since you get an error :)

It's theoretically impossible to access a class's private (and protected) variables, and that's a great decision. But if you still want to do it (and sometimes it's just necessary), the most common way is to use getters and setters:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Player
{
public:
    int getLives() const { return m_lives; } // returns the value of lives
    void setLives( int lives ) { m_lives = lives; } // sets the value of lives

private:
    int m_lives;
};

int main()
{
    Player player;
    
    // Set player's lives
    player.setLives( 3 );

    // Output the player's lives
    std::cout << player.getLives() << std::endl;

    return 0;
}


EDIT: a better solution is one post down :)
Last edited on
@Fransje

I know the OP is a beginner & your answer was an easy one, but best not to point them towards bad practise already. I know you probably know better - I am just saying don't downgrade your advice to the point where it is bad practise.

@cppbeginner1

We had a huge discussion about get / set functions here:

http://www.cplusplus.com/forum/lounge/101305/


One of the most obvious points is that trivial public set functions which are straight assignment are really bad. You wouldn't like anyone to set your bank balance to -1000000.00 would you?

Better in this case to use a constructor with initialiser list, and a member function called print say:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Player
{
private:
    int m_lives;

public:
    int getLives() const { return m_lives; } // returns the value of lives
    void setLives( int lives ) { m_lives = lives; } // sets the value of lives

    Player(int NumLives) : m_lives(NumLives) {} // constructor with initialiser list

    void Print(); //Print out the values 


};

void Player::Print() {
    std::cout << m_lives << std::endl;
}

int main()
{
    // constructor a Player & set lives
    Player player(3);
    
    // Set player's lives
    player.setLives( 3 );

    // Output the player's lives
    std::cout << player.getLives() << std::endl;
    player.Print();

    return 0;
}



Notice how I separated out the definition of the print function? Usually we have the class declaration in a header file (.h) and the function definitions in a .cpp file.

Edit:

So this would have 3 files Player.h Player.cpp and main.cpp.

HTH
Last edited on
@TheIdeasMan: yeah, you're right. I hadn't thought of a ctor together with a print function, that's better design indeed.

One of the most obvious points is that trivial public set functions which are straight assignment are really bad. You wouldn't like anyone to set your bank balance to -1000000.00 would you?

But since it's such a simple assignment, I just wanted to show the getters/setters concept.
Last edited on
@Fransje

But it is a bad concept - as I said above, don't downgrade your advice.

Imagine the OP takes your advice on board, and writes thousands of LOC over the next year - only to discover the hard way that it is all wrong.

@cppbeginner1

I notice you have a variable called string which is an array of char. Try to avoid using a variable name that is the same as a C++ keyword. Why not use a C++ string type instead of array of char?
^ `string' is not a keyword.
DIt is if he is using the whole std namespace or using std::string
I agree with ne555. std::string is a class, not a keyword. It does emulate a keyword, though.
I wanted to know how to access my private variable.

To probably state the obvious: the whole point of making a class member private is to stop other code (not part of the class) from getting access to it. That's why it's called private!

If you do need to access a member (with usual caveats about it being something you should only use appropriately) you need to provide an accessor.

If it's a hurried piece of prototype code, I would probably just make the member public. But that would not make it to "real" code.

(While I'm here, the member char string[]; does not declare any room for storage. You need to provide a size here as zero sized arrays cannot be used to store anything.)

On the subject of getters and setters, it is right that there should not be overuse. But in the general case I would not go as far as TheIdeasMan in altering Fransje's class:
- I would drop the setter and use an initializing constructor
- But I would keep the getScore rather than replacing it with a Display method.

This is because I do not like to introduce coupling between the GUI (cout is the console GUI) and the data model. Ideally the class can be reused as-in with an alternative GUI (e.g. in a Win32 app.)

(I say generally as I would use a Print() methods in code for a little console based tool. Though usually it would be a void print(ostream& os); method so I would reuse it with an ifstream as well as cout)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <string>
using namespace std;

class Player
{
private:
    string m_name;
    int    m_lives;
public:
    Player(const string& name, int NumLives)
    : m_name(name), m_lives(NumLives) {}

    const string& getName() const { return m_name; }
    int getLives() const { return m_lives; }
};

// OK, it is a toy example, but a function called DisplayPlayer()
// or method Player::Display() does sound like it should display the
// whole public state of the player rather that just the value of age
void DisplayPlayer(const Player& player) {
    std::cout << "Player:\n"
              << "name  = " << player.getName() << "\n"
              << "lives = " << player.getLives() << std::endl;
}

int main()
{
    // construct a Player & set lives
    Player player("Fred", 3);

    // Output the player's details
    DisplayPlayer(player);

    return 0;
}


For purely illustrative purposes, this is a severely dumbed down piece of Win32 GDI code. It uses the same Player class, but now through a pointer. The point being that class Player would have to do a lot of GDI specifc work it it had to draw itself (real code would be changing the font, background, etc and drawing borders and the like.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// Apologies for the "magic numbers" and ltoa and lack of TCHARs...
void DisplayPlayer(HDC hdc, const Player* pPlayer)
{
	const char labelPlayer[] = "Player";
	const char labelName  [] = "Name";
	const char labelLives [] = "Lives";

	const COLORREF crefRed   = RGB(255,   0,   0);
	const COLORREF crefGreen = RGB(  0, 255,   0);
	const COLORREF crefBlue  = RGB(  0,   0, 255);

	char displayTest[1024] = "";

	COLORREF crefTextOld = SetTextColor(hdc, crefRed);
	TextOut(hdc, 10, 10, labelPlayer, strlen(labelPlayer)); // evil "magic numbers"

	SetTextColor(hdc, crefGreen);
	TextOut(hdc, 10, 30, labelName, strlen(labelName));

	SetTextColor(hdc, crefBlue);
	const std::string& name = pPlayer->getName();
	TextOut(hdc, 60, 30, name.c_str(), name.length());

	SetTextColor(hdc, crefGreen);
	TextOut(hdc, 10, 50, labelLives, strlen(labelLives));

	SetTextColor(hdc, crefBlue);
	char ageAsStr[16] = "";
	ltoa(pPlayer->getLives(), ageAsStr, 10); // lazy demo code :-(
	TextOut(hdc, 60, 50, ageAsStr, strlen(ageAsStr));

	SetTextColor(hdc, crefTextOld);
}

Last edited on
We haven't had any replies from the OP - are they trolling?
Topic archived. No new replies allowed.