C++ Question with classes [SOLVED]

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
DTKilb
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 9
Joined: Sat Aug 06, 2011 9:43 pm

C++ Question with classes [SOLVED]

Post by DTKilb »

Hello, I've been working on learning C++ and have been making my own small projects recently. I'm currently trying to make a small text based RPG using C++. In the process, I've been trying to use multiple files and classes for experience. So far, I've been doing things such as making a player file holding a class that contains all of the player's variables. Such as health,
playerLevel, gold, etc. I'd later make separate files that contain the game play for specific levels in the game. Such as a level1.h/level1.cpp. In the process, I've included the player file into the level1.cpp in order to get the players gold/level for reasons such as shops or combat. But whenever I try to make an object of the player class, such as "player p;" and try and, for an example, display the player's health "cout << p.health;" the value is completely different from what it is initialized to. My question is to what is causing this problem and how I can stop this from happening in the future.
Here is a quick example to make my situation more clear.

Main.cpp:

Code: Select all

#include <iostream>
#include "example1.h"
#include "example2.h"
using namespace std;

int main(){
	example1 ex1;
        example2 ex2;
	ex1.initVariables();	
	ex2.startLevel();
}
Example1.h:

Code: Select all

#include <iostream>
using namespace std;

class example1{
public:
	void initVariables();
	int playerHealth, playerGold;

};
Example1.cpp:

Code: Select all

#include <iostream>
#include "example1.h"
using namespace std;

void example1::initvariables(){
	playerHealth = 100;
	playerGold = 100;
}
Example2.h:

Code: Select all

#include <iostream>
using namespace std;

class example2{
public:
	void startLevel;
};
Example2.cpp:

Code: Select all

#include <iostream>
#include "example2.h"
#include "example1.h"
using namespace std;

void example2::startLevel(){
	example1 ex1;
	cout << "Your Health: " << ex1.playerHealth; //When displayed, this is NOT 100 (what it was initialized to)
	cout << "Your Finances: " << ex1.playerGold << " gold"; //Not what it was initialized too, either.

}
Last edited by DTKilb on Wed Aug 24, 2011 7:02 pm, edited 1 time in total.
JesseGuarascia
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 70
Joined: Mon Dec 13, 2010 10:55 pm

Re: C++ Question with classes

Post by JesseGuarascia »

Well for starters, what you're doing is a mistake I made at first, too :P Variables have something called "scope" applied to them. Scope is kind of like a sniper scope. Different parts of your code can only see things that are in their scope. The main function in main.cpp has the variable ex1 in it's scope at all times. In your main.cpp, you have your main function where you declare the first ex1 variable, putting it into the main functions "scope". There's global and local scope: Global means all functions that know that variables name (have it included or declared outside of all functions). Local means that the variable is created inside of the function, meaning that only that function has access to the variable. So with the idea that each function can only see variables it's given scope to, look at your second class' startLevel function:

Code: Select all

#include <iostream>
#include "example2.h"
#include "example1.h"
using namespace std;

void example2::startLevel(){
   example1 ex1;
   cout << "Your Health: " << ex1.playerHealth; //When displayed, this is NOT 100 (what it was initialized to)
   cout << "Your Finances: " << ex1.playerGold << " gold"; //Not what it was initialized too, either.

}
By creating a new ex1 of the type example1, you're not accessing the same variable declared in your main function. The ex1 in example2's startLevel function is local to that function, and ex1 of the type example1 in main.cpp's main function can only be seen by the main function. In order to have access to the variable ex1 that you initialized in the main function, you'd have to make that variable completely global. Here's my suggestion for a beginner:

Create a file that has the variable globally.

Player.h:

Code: Select all

#ifndef PLAYER_H_
#define PLAYER_H_

#include "example1.h"
extern example1 ex1;

#endif // PLAYER_H_
Player.cpp:

Code: Select all

#include "Player.h"

example1 ex1;
This is HORRIBLE practice, but since you're just a beginner with classes, I'm not going to get into polymorphism and inheritance and manager classes. Lemme know if this works out for you, or if you have any other questions :)
-- Jesse Guarascia

I like C/++, SDL, SFML, OpenGL and Lua. If you don't like those, then gtfo my sig pl0x (jk trollololololol)
DTKilb
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 9
Joined: Sat Aug 06, 2011 9:43 pm

Re: C++ Question with classes

Post by DTKilb »

Thank you so much for your help!
Also, I've noticed something that I've run into a lot online, where people place in arguments with their functions with things such as:

Code: Select all

void example1(example2& ex1){ }
Could that have anything to do with my issue in any way?
JesseGuarascia
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 70
Joined: Mon Dec 13, 2010 10:55 pm

Re: C++ Question with classes

Post by JesseGuarascia »

All this is, is a function who has an argument that is a reference :) A reference is almost a complete copy of a variable, but it has the exact same memory address. It's sort of like taking a variable and momentarily moving it somewhere else, only to move it back once it's done what it needs to do. That's another great way of giving the information, but I wasn't sure to what extent you understood things like that. :P I didn't want to go an suggest something I wasn't sure you knew or not :)

If you were to use references in your example, all you would have to do is change your startLevel function to something like this:

Example2.h:

Code: Select all

class example2{
public:
    void startLevel(example1 &ex1);
}
Example2.cpp:

Code: Select all

void example2::startLevel(example1 &ex1){
   cout << "Your Health: " << ex1.playerHealth; //When displayed, this is NOT 100 (what it was initialized to)
   cout << "Your Finances: " << ex1.playerGold << " gold"; //Not what it was initialized too, either.
}
From the example code you gave for the function, though, you wouldn't need to use a reference. Just make the same changes, but don't put the ampersand (&). Either way should work fine :)
-- Jesse Guarascia

I like C/++, SDL, SFML, OpenGL and Lua. If you don't like those, then gtfo my sig pl0x (jk trollololololol)
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: C++ Question with classes

Post by short »

A reference is almost a complete copy of a variable,
No.... just....... no.....

A reference is a just that, a reference. If you make changes to a reference inside an object, when your return from the function the object you passed a reference of has still been modified. It's because your only ever working with one object, there are no copies when passing by reference. When you pass a reference to a function, its just a memory address.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
ibly31
Chaos Rift Junior
Chaos Rift Junior
Posts: 312
Joined: Thu Feb 19, 2009 8:47 pm
Current Project: Like... seven different ones
Favorite Gaming Platforms: Xbox 360, Gamecube
Programming Language of Choice: C++, ObjC
Location: New Jersey.

Re: C++ Question with classes

Post by ibly31 »

@short
I thought that that's what pointers did. Like I thought if you wanted to modify an object, you passed by pointer, not reference. I'm so confused by C++'s memory stuff, thats why I use ObjC :)
Image
Twitter
Website/Tumblr
My Projects

The best thing about UDP jokes is that I don’t care if you get them or not.
JesseGuarascia
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 70
Joined: Mon Dec 13, 2010 10:55 pm

Re: C++ Question with classes

Post by JesseGuarascia »

short wrote:
A reference is almost a complete copy of a variable,
No.... just....... no.....

A reference is a just that, a reference. If you make changes to a reference inside an object, when your return from the function the object you passed a reference of has still been modified. It's because your only ever working with one object, there are no copies when passing by reference. When you pass a reference to a function, its just a memory address.
So clearly, you read that part of that one sentence and decided to write a response.
JesseGuarascia wrote: A reference is almost a complete copy of a variable, but with the exact same memory address. It's sort of like taking a variable and momentarily moving it somewhere else, only to move it back once it's done what it needs to do.
-- Jesse Guarascia

I like C/++, SDL, SFML, OpenGL and Lua. If you don't like those, then gtfo my sig pl0x (jk trollololololol)
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: C++ Question with classes

Post by short »

So clearly, you read that part of that one sentence and decided to write a response.
Reading the word copy was enough (of course I read your whole post). Sorry if it sounded rude.
A reference is almost a complete copy of a variable, but with the exact same memory address. It's sort of like taking a variable and momentarily moving it somewhere else, only to move it back once it's done what it needs to do.
This explanation is weird (to me) because there is no moving done what-so-ever, and I thought it help both of you to consider exactly what a reference does, not talk about it in terms of moving things and making copies when neither is done.

A pointer is similar to a reference, but having a pointer to an object allows you to do operations "on the pointer" such as addition (visit each element of an array). The reference is like having a constant pointer (that the only operation you can do is de-referencing), you can't do any operations on the pointer itself, because, well it's constant. You can operate on a reference with the . notation, (as opposed to de-referencing a pointer with the -> operator). Yes Ibly, pointers and references are very similar, when working at this level of programming.


An extremely strong/easy to understand example is consider that Java C# passes all objects by reference.
(please ignore that you generally cannot define a function within another function, like I do below, in all 3 examples)
C# code

Code: Select all

Object j = new Object();
j.arg1 = 100;
Whatevs(j);

void Whatevs(object j) {
    j.arg1 = 35;
}

println(j.arg1);
output: 35;
Since C# passed in j by reference (ie j's memory address) to Whatevs, j could modify j directly. Thus later when j.arg1 was printed in the calling function scope, j's value had been modified to 35.

Consider the same example in C++ which passes all values/types by COPY (by default)

Code: Select all

Object *j = new Object();
j->arg1 = 100;
Whatevs(*j);

// by passing in j to Whatevs(), a copy of j is made and given to Whatevs() to operate on.
void Whatevs(object j) {
    j.arg1 = 35;
}
println(j.arg1);
delete j;
Thus is it obvious the output is 100;

To get the same effect as the c# model of passing objects (by reference) we simply use the & syntax.

Code: Select all

Object *j = new Object();
j->arg1 = 100;

// all changes made to j inside Whatevs will persist, as no copy is made. We are passing Whatevs the memory address j is stored at in memory, so it can modify the object directly in memory.

Whatevs(*j); // this will still passed by reference
// or we can declare a local j, modify its arg1, and pass by reference 
Object k;
k.arg1 = 100;
Whatevs(k);

void Whatevs(object &j) {
    j.arg1 = 35; // notice . syntax
}

println(j->arg1);
delete j;
println(k.arg1);
output: 35
and
output: 35;
I hope this is more clear. JesseGuarascia I didn't mean to be rude, I apologize.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: C++ Question with classes

Post by Falco Girgis »

JesseGuarascia wrote: A reference is almost a complete copy of a variable, but with the exact same memory address. It's sort of like taking a variable and momentarily moving it somewhere else, only to move it back once it's done what it needs to do.
This is a contradiction by definition. "Copy" and "same memory address" are not compatible. It's nothing at all like taking a variable and moving it.

A C++ reference is LITERALLY an auto-dereferenced C pointer. If you look at any disassembly, they are equivalent behind the scenes. The C++ syntax spares you from having to pass memory addresses around and use pointer indirection, but it is literally doing the same thing.
Pornomag
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 41
Joined: Tue Jun 21, 2011 5:39 am
Programming Language of Choice: C++

Re: C++ Question with classes

Post by Pornomag »

ibly31 wrote:@short
I thought that that's what pointers did. Like I thought if you wanted to modify an object, you passed by pointer, not reference. I'm so confused by C++'s memory stuff, thats why I use ObjC :)
That's why you use Objective-C? What the hell?! Objective-C has pointers (I'm not sure about references, but a reference is a pointer in some term). Objective-C is a strict super set of C.

If anything Objective-C memory management is harder, every object of a class you make has to be a pointer and if you want to use it you have to usually call alloc, new or copy. And then it has to call release sometime later in your program unless it's an autorelease object.
Pornomag
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 41
Joined: Tue Jun 21, 2011 5:39 am
Programming Language of Choice: C++

Re: C++ Question with classes

Post by Pornomag »

Oh and here's a quick overview of what you should do in classes. To initialise variables when you create an object you use a constructor and an initialiser list when possible. If however you don't want to initialise variables as soon as the Object of your class is create you can set them manually. Another note is to always try and keep your variables PRIVATE, therefore no one can touch them and play around with them directly. You use getters/setters to set and get your variables, but if it's a pointer if you create a getter then someone can indirectly modify your private data with ease. Here is an example of what a class usually should be like.

Code: Select all

class Example{
private:
      int x;
public:
// Default constructor that initialises x to 0
      Example()
      : x(0) // Same as saying x = 0*
      {
      }
// A custom constructor that initialises x to a custom value
     Example(int value)
     : x(value) // Same as saying x = value*
     {
     }
// Some getters and setters
     int getX() const { return x; } 
/*
The const keyword after the function 
tells the compiler that no variables are 
modified and can be used with a const Object of this class
*/
     void setX(int value) { x = value; }
};
Notes:
In your class it is good programming practice to not access the private data directly, you should use your getter/setter function.
Another note is that, when you define the body of a function inside your class, the function is usually implicitly inlined for you, depending on your compiler/settings and if it can be inlined.
*You could set x to those values in the body of the constructor, but a initialiser list initialises the variables before the body is reached.

You should read more about classes in a book or some websites, I really recommend a book because it will be more informative because they get payed for writing a whole book. But you could also check this website about learning C++: http://www.cplusplus.com/doc/
And seeing as your learning classes here's the direct links for the articles about classes in C++
http://www.cplusplus.com/doc/tutorial/classes/
http://www.cplusplus.com/doc/tutorial/classes2/
Post Reply