Problem with declaring a member variable as static ALMOST SOLVED!

Started by
18 comments, last by ZQJ 18 years, 10 months ago
I'm trying to do a very simple thing and keep getting linker errors in DevC. I have a class called Actor, which stores details for characters in a game. I have no problem declaring this:

public:
	int s_Total;



and accessing it in the constructor like this:

Actor::Actor()
{
	s_Total=0;
}



At this stage I'm keeping things simple, I'm not trying to do anything else with it whatsoever, and yet when I try to declare the variable as static I get an error. I change the declaration to this:

public:
	const int s_Total;



And suddenly I get this error: [Linker error] undefined reference to `Actor::s_Total' Could this be a problem with the compiler or am I missing something? Any help appreciated... [Edited by - darenking on June 21, 2005 2:50:51 AM]
Advertisement
i believe you're looking to do this...
class myclass {static int s_i;};int myclass::s_i = 0;

This space for rent.
Note that static does not mean the same thing as const, so I'm a bit confused as to what you're actually trying to achieve.

const makes a member variable constant. That means, its value must be set in the initialization list of the constructor, and once set, it cannot change. Any attempt to set it to another value anywhere else in the code will result in a compiler error.

This means your constructor should look something like this:
Actor::Actor() :s_Total(0){}

static declares a member variable that is globally shared by all members of the class. You don't need an instance of your class to access it, but any changes you make to it will change it for any and all instances of that class that do exist.

If this is what you're trying to do, your code should look something like this:

// In the declaration (header file)class Actor{// blah blah blahpublic:   static int s_Total;// blah blah blah};// in the definition (CPP file)int Actor::s_Total = 0;Actor::Actor(){   // no need to set s_Total here - it's already set   // however if we need to change it, e.g for a reference count, we'd do something like this:   ++s_Total;}


Note that in the second example, s_Total is essentially global to your entire application. Any piece of code can come along and modify it, so it wouldn't be a very safe reference count. If you only want your Actor class to modify it, make it private.
Okay ... look at what your doing. Your telling a variable to not be modifiable then your modifing it. It can't be done. The only way to make something static like that is to declare it that way in the beginning. (i.e const int x = 2;)
Whoops!

When I typed const in my post above I meant to type static, got in a muddle with another problem I was having. I definitely typed static in my program.

Forget all the const stuff, the problem was definitely with statics.

OK, I've looked at the examples above and the problem seems to be that I didn't have this bit:

// in the definition (CPP file)int Actor::s_Total = 0; // <-------------- this bit here!!!Actor::Actor(){etc


I've put it in and it now works.

But why do we need it? Aren't we already declaring it in the function header, in the .h file? I have this:


privatestatic int s_Total;


Doesn't that declare it or something?
It does declare it, but when using static it means that it is the only instance of it in the program or class. Therefore any time in the class when you reference that variable, regardless of how many times you've instantiated it, it will always be the same. Therefore if you have two instances of the class, that variable will be the same in both. If you change it in one, it will also update in the other.
Original post by darenking
privatestatic int s_Total;


Doesn't that declare it or something?

Yes, it declares the variable. But this statement does not allocate memory for the variable (it does not defined it). So you have to define this static variable in an object file. To avoid linker errors because of duplicate definitions, never put the definition into a header file.
Quote:But this statement does not allocate memory for the variable (it does not defined it).


Yeah, that's the bit I don't get, as surely with non static variables memory is allocated for it at that point in the header file?

Is it because, if it were to allocate memory for it at that point, it would end up allocating the memory for it every time an instance of the object is created?

I may be a bit off, but let me try this:
Quote:Original post by darenking
Yeah, that's the bit I don't get, as surely with non static variables memory is allocated for it at that point in the header file?

Is it because, if it were to allocate memory for it at that point, it would end up allocating the memory for it every time an instance of the object is created?

Class declarations in header files don't allocate memory, because they don't create anything. Look at this:
class foo1{	int bar; //this doesn't allocate any memory};

That says, "Foo class objects contain an int called bar." But no memory is allocated for the member variable until a foo object is created. The code above is just a blueprint; no space has been set aside.

Now let's add a static var:
class foo2{	int 		bar;  //this doesn't allocate any memory	static int 	yada; //neither does this};

Now, the same thing is true for yada as for bar. No memory has been allocated for it. But since it is a static member variable, it doesn't get created when an instance of the class does. So, it needs the line
int foo::yada = 0;
to actually allocate the memory for it.
That explains it perfectly! Thanks!


This topic is closed to new replies.

Advertisement