C++ - Accessing Private Variables

I had a c++ project due today. I definitely got an F on it. The main reason behind that was that one of my methods wasn't functioning properly. I had a private integer variable declared within a class and an adder method to access it however when that method was called it would never change the variable. What was I doing wrong?

Well I tried to write a sample program to try to show what it was doing, but It worked fine in my sample. So I just took a couple of of methods that weren't working and posted them here. See what you think. I'm definitely stumped.

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#include <iostream>
#include <time.h>


   using namespace std;

   const int randSeed(time(NULL));
   const int ATTRIBUTES = 25;
   const int DIMENSION = 26;

   class Player	{
      int time;
      int intel;
      int money;
      int  fun;
      int position[2];
   	
   /**
   ** The player class constructor. Will generate a new player object.
   */ 
   public:
      Player()	{
         srand(randSeed);
         int random = (rand() % 4) + 1;
      //picks the starting location of the player
         switch(random)	{
            default:
               position[0] = 0;
               position[1] = 0;
               break;
         }
         //set the value of fun, time, money, intel.
         fun = ATTRIBUTES + (rand() % 10);
         intel = ATTRIBUTES + (rand() % 10);
         money = ATTRIBUTES + (rand() % 10);
         time = ATTRIBUTES + (rand() % 10);
      }
   
   /** 
   **	The method addMoney adds (or subtracts) a specified
   ** ammount of money.
   **	@param ammount The ammount of money to be added.
   **	@return The current money balance of this player.
   */
   public:
      int addMoney(int ammount)	{
         int moneyNew = money + ammount;
         money = moneyNew;
         return money;
      }
   
   /** 
   **	This method gets and returns this player's current
   ** money balance.
   **/
   public:
      int getMoney()	{
         return money;
      }
      
   /** 
   **	The method addTime adds (or subtracts) a specified
   ** ammount of time.
   **	@param ammount The ammount of time to be added.
   **	@return The ammunt of time remaining.
   */
   public:
      int addTime(int ammount)	{
         int timeNew = time + ammount; 		
         time = timeNew;
         return time;
      }
   
   /**
   ** This method ruturns the current ammount of time remaining.
   */   
   public:
      int getTime()	{
         return time;
      }
   
   /**
   ** Will add a given ammount of inteligence to the players current level.
   **	@param ammount The ammount of inteligence to be added.
   **	@return The players current intelegence.
   */
   public:
      int addIntel(int ammount)	{
         int intelNew = intel + ammount;
         intel = intelNew;
         return intel;
      }
    /** Will get the current value of intel. */  
    public:
      int getIntel()	{
         return intel;
      }
    
   /** Returns a boolen value of 'true' if player is dead */
   public:
      bool isDead()	{
         return (money <= 0) || (time <= 0) || (intel <= 0) || (fun <= 0);
      }
   
   /** Returns the current value of fun. */
   public:
      int getFun()	{
         return fun;
      }
      
   /**
   ** Will add a given ammount of fun to the players current level.
   **	@param ammount The ammount of fun to be added.
   **	@return The players current fun.
   */ 
   public:
      int addFun(int ammount)	{
         int funNew = fun + ammount;
         fun = funNew;
         return fun;
      }
   
   /** Gets the array value of position	*/
   public:
      int *getPosition()		{
         return position;
      }
   
   /** Returns a boolean value indicating if the player has reached the finish.
   */
   public:
      bool isFinished()	{
         return position[1] == (DIMENSION - 1);
      }
   
   /**
   ** Sets the player position to a desired value.
   ** @param x The position of the player in the x dimension.
   **	@param y The position of the player in the y direction.
   */
   public:
      void setPosition(int x, int y)	{
         position[0] = x;
         position[1] = y;
      }
      
   public:
      int calcScore()	{
         float score = time * 0.1 + money * 0.3 + intel * 0.3
            + fun * 0.3;
         return (int)score;
      }
   
   /** Returns a string representation of this player*/
   public:
      void toString()	{
         cout << "You have:\nTime: ";
         cout << time;
         cout << "\nIntel: ";
         cout << intel;
         cout << "\nMoney: ";
         cout << "$" << money;
         cout << "\nFun: ";
         cout << fun;
         cout << "\nPlayer position:\n";
         return;
      }
   };
	/** Method adjust a players attributes based on what type of work
	is being done. */  
   void doWork(Player playerIn)	{
      
      int userInput = 0;
      do	{
         cout << "What kind of work do you want to do?" << endl 
            << "1) Search for loose change (boosts money, takes time)"
            << endl << "2) Read technical papers (boosts intel, takes time)"
            << endl << "3) Buy some time (Gain time but spend money)"
            << endl << "4) Hit the bars (It's fun, but costs money, "
            << "small chance of loosing intel)" << endl << "Choose an option: ";
         cin >> userInput;
         if(userInput != 1 && userInput != 2 && userInput != 3 && userInput != 4)	{
            cout << "ERROR::Invalid Input" << endl;
            userInput = 0;
         }
      }
      while(userInput == 0);
      srand(time(NULL));
      switch(userInput)	{
      	//boost money
         case 1:
            playerIn.addMoney(1 + rand() % 5);
            playerIn.addTime(-1 * (1 + rand() % 5));
            break;
      	
      	//boost intel
         case 2:
            playerIn.addIntel(1 + rand() % 5);
            playerIn.addTime(-1 * (1 + rand() % 5));
            break;
      	
      	//boost time
         case 3:
            playerIn.addTime(1 + rand() % 5);
            playerIn.addMoney(-1 * (1 + rand() % 5));
            break;
      	
      	//have fun
         case 4:
            playerIn.addFun(1 + rand() % 5);
            playerIn.addMoney(-1 * (1 + rand() % 5));
            if((rand() % 4) == 0)	{
               playerIn.addIntel(-1 * (1 + rand() % 5));
            }
            break;
      }		
   }
   int main()	{
      Player p = Player();
      p.toString();
      cout << endl;
      doWork(p);
      cout << endl;
      p.toString();
   }


So you ran this code, and what specifically didn't work?
The main problem is most likely here:
void doWork(Player playerIn) {
You pass playerIn by value, which means that a copy of the object will be made. Any changes you make to it don't leave the function. If you want to modify the original object, you need to pass by reference:
Player& playerIn

There's some other strange things going on. For example, you seed the random number generator in several places, but you should have just one call srand(time(NULL)); at the beginning of your program.

The switch(random) in the constructor is also a bit strange, since it doesn't do anything (unless you wanted to add more positions later).

addMoney and addTime seem a bit verbose; you can write
1
2
money+=amount;
return money;

or even return money+=amount;

The getters should be const, as they don't modify the Player object.

toString() should return a string, not print something. You can achieve that by sending the output to a stringstream object instead of cout and returning the result at the end.

And in this line you actually create two player objects: Player p = Player();
Player() creates a temporary player object and then copy constructs p with it. Player p; is sufficient.
Ok so I'm posting the output now and as you may or may not be able to tell. When the method doWork calls addTime and addMoney (lines 192,193) the program should branch to those methods and add the specified amount to the int variables time & money. However It's not doing that, and you can see that when I call the Player::toString method. Notice that both times when I call the toString method the output is exactly the same. The values for time and money should be different, however, after the call to their respective adder methods.

Here's the output to the program above:

You have:
Time: 32
Intel: 25
Money: $29
Fun: 34
Player position:

What kind of work do you want to do?
1) Search for loose change (boosts money, takes time)
2) Read technical papers (boosts intel, takes time)
3) Buy some time (Gain time but spend money)
4) Hit the bars (It's fun, but costs money, small chance of loosing intel)
Choose an option: 1

You have:
Time: 32
Intel: 25
Money: $29
Fun: 34
Player position:

Last edited on
So It should be written like this?
 
void doWork(Player& playerIn)

Also, I'm aware that adder method is kind of redundant. I just started changing it randomly to try and fix my problem.

Future note: Always pass objects by reference?
Last edited on
If you want to modify the object that is being passed, then yes. If you want a copy, don't.
Topic archived. No new replies allowed.