Need help making a class member object 'static
by Steven Peterson · in Technical Issues · 04/09/2006 (8:52 pm) · 7 replies
In TGE(C++), I have an abstract-base-class with a data-member in the protected section(see code below). When I declare it normally it just works, nothing else is needed. However I want all child classes to access the SAME data-member, so it should be STATIC.
Where it gets confusing is that after declaring the data-member 'static' i'm required to "intilize it at file scope". I have numerous other staitics in my *.h files and I do this at the top of the corresponding *.cc. Since this data-member is an object-instance ( in fact a data-structure) though, there's nothing as far as I can tell to "initilize".
So how do I propperly declare it static, and either initilize it or beat out the linking error that results from not?
My book doesn't cover this case, and a quick google / GG search didn't turn it up, and I've been racking my brain for 24+ hours now :-( The only solution I can find is to make the whole thing a STATIC POINTER to my object; but that just seems like an extra (unwanted) level of abstraction.
- "List" is a custom dynamically-linked-list template class.
- "MyDataType" is a simple struct
Thanks all,
Steven
Where it gets confusing is that after declaring the data-member 'static' i'm required to "intilize it at file scope". I have numerous other staitics in my *.h files and I do this at the top of the corresponding *.cc. Since this data-member is an object-instance ( in fact a data-structure) though, there's nothing as far as I can tell to "initilize".
So how do I propperly declare it static, and either initilize it or beat out the linking error that results from not?
My book doesn't cover this case, and a quick google / GG search didn't turn it up, and I've been racking my brain for 24+ hours now :-( The only solution I can find is to make the whole thing a STATIC POINTER to my object; but that just seems like an extra (unwanted) level of abstraction.
- "List" is a custom dynamically-linked-list template class.
- "MyDataType" is a simple struct
class TskEvent {
public:
...
protected:
[b]static[/b] List< MyDataType* > mMyList;
private:
void myFunction() = 0;
}Thanks all,
Steven
#2
I'm sure there's a way - but it doesn't seem to be documented anywhere.
04/09/2006 (10:19 pm)
Thanks, but I just read it and it doesn't seem to cover this case ( static class member object ?). :-(I'm sure there's a way - but it doesn't seem to be documented anywhere.
#3
yeah, there's a trick.
basically you need to initialize the variable in a global scope,
eg at the begining of the .cc file for the class.
here's an example with a simpler data-type than List:
myClass.h
myClass.cc
see for example mLagThresholdMS in GameConnection; it's pretty much exactly what you want to do except w/ a simpler data-type.
04/09/2006 (11:41 pm)
Hey steven -yeah, there's a trick.
basically you need to initialize the variable in a global scope,
eg at the begining of the .cc file for the class.
here's an example with a simpler data-type than List
myClass.h
class myClass {
// ...
static S32 mMyVar;
// ..
};myClass.cc
// #includes, blah blah S32 myClass::mMyVar = 0; // rest of class implementation
see for example mLagThresholdMS in GameConnection; it's pretty much exactly what you want to do except w/ a simpler data-type.
#4
definition file:
implementation file:
for your case I guess it'd be:
objectType Class::objectName = new objectType(initializers);
yeah...that looks right.
04/10/2006 (8:15 am)
Yeah what Steven said is correct and IS also covered in the reference I posted above in chapter 10. like Steven says, you need to just use a scope resolution operator :: to initialize the variable like accessing a namespace. heres the code from the reference example:definition file:
class Directory
{
static char s_path[];
public:
// constructors, destructors, etc. (not shown)
};implementation file:
include "directory.ih"
char Directory::s_path[200] = "/usr/local";for your case I guess it'd be:
objectType Class::objectName = new objectType(initializers);
yeah...that looks right.
#5
heh, maybe I explained it poorly - but I've done this LOTS with simple data-types (which seems to include arrays here), and pointers. I was confused because an object is not a simple data-type. So most of those examples were just rehashing old knowlege.. :-(
Sean, in your last idea new automatically implies dynamic memory allocation - ie. pointes. It would have to look like this:
class *.h
class *.cc
I was hopeing to avoid this since I have enough pointers in my head already. But for some reason your "objectType(initializers)" got me thinking about the constructor again. And that ended up being the key. Final soultion was this:
class *.h
class *.cc
And with the templates back in:
class *.h
class *.cc
Thanks Sean & Orion, for sticking with me on this one!
04/10/2006 (9:39 am)
I win! (I think..)heh, maybe I explained it poorly - but I've done this LOTS with simple data-types (which seems to include arrays here), and pointers. I was confused because an object is not a simple data-type. So most of those examples were just rehashing old knowlege.. :-(
Sean, in your last idea new automatically implies dynamic memory allocation - ie. pointes. It would have to look like this:
class *.h
satic objectType *objectName;
class *.cc
objectType *Class::objectName = new objectType(initializers);
I was hopeing to avoid this since I have enough pointers in my head already. But for some reason your "objectType(initializers)" got me thinking about the constructor again. And that ended up being the key. Final soultion was this:
class *.h
static ObjectType mObjectName;
class *.cc
ObjectType MyClass::mObjectName = ObjectType();
And with the templates back in:
class *.h
static ObjectType< DataType* > mObjectName;
class *.cc
ObjectType< DataType* > MyClass::mObjectName = ObjectType< DataType*>();
Thanks Sean & Orion, for sticking with me on this one!
#6
04/10/2006 (9:46 am)
Ps. It compiles now - god only knows if it will actually work!.. :-P
#7
one final two-cents,
instanciating a non-simple datatype like a potentially ornate class at global scope seems a bit weird.
the object is going to be instanciated basically before the application starts executing,
which in my experience is a weird somewhat undefined state of things.
for example possibly DLLs haven't been loaded yet.
it seems more robust to me to initialize it to NULL and then allocate an actual instance during some initialization routine. or in an accessor:
eg in MyClass.cc
04/10/2006 (10:42 am)
Glad it's CC'ing Steven.one final two-cents,
instanciating a non-simple datatype like a potentially ornate class at global scope seems a bit weird.
the object is going to be instanciated basically before the application starts executing,
which in my experience is a weird somewhat undefined state of things.
for example possibly DLLs haven't been loaded yet.
it seems more robust to me to initialize it to NULL and then allocate an actual instance during some initialization routine. or in an accessor:
eg in MyClass.cc
ObjectType< DataType*> MyClass::getMyObject()
{
if (!mObjectName)
mObjectName = ObjectType< DataType*>();
return mObjectName;
}
Torque 3D Owner Sean H.
check out chapter 10.