Sign in to follow this  

C++ Constructor/Static Member Variable Question

This topic is 4752 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am making a game. In it, each item is represented by a class inheriting Item This is the one for a fence: class Fence : public Item { //...Some private stuff static Picture _FencePic; public: static void InitPicture(); //... more stuff } ; Anywho, the picture class (the stuff pertaning to the question) goes like this: class Picture { static std::list<Picture*> _img_lst; //List of all the images created. Used for restoration public: Picture() { Picture::_img_lst.push_back(this); //ERROR } }; Anywho, it seems the _FencePic is created before _img_lst because when I run the program, it has an error on the line marked. Whats going on?

Share this post


Link to post
Share on other sites
The order of construction of static variables in different translation units is undefined. If you want Picture::_img_list to be created before Fence::_FencePic, you'd have to define them in the same source file, and define Picture::_img_list before Fence::_FencePic.

Alternately, you could look into singleton methods that would guarantee construction upon use, but in general, if you're doing something that relies on depending on the order of construction of static objects, you might want to rethink your design somewhat.

Share this post


Link to post
Share on other sites
Quote:
Original post by Rob Loach
That's what happens with inherited constructors. The constructor for the inherited object is called first. I don't know of a way to switch it around.

Umm, that has nothing to do with it... it's because in C++ the construction order of static variables is only defined when the variables are in the same translation unit (.cpp file), and the order in the same translation unit is defined by the order in which they are declared, it has nothing to do with if one instance uses another. Just because the instance of Picture is constructed as _FencePic doesn't mean that the instance of std::list<Picture*> is constructed as _img_list before hand.

I think your best bet here would be to do something like this:


class Fence : public Item
{
//...Some private stuff
static Picture *_FencePic;
public:
static void InitPicture();
static void UninitPicture();
//... more stuff
} ;

void Fence::InitPicture()
{
_FencePic = new Picture;
//...
}

void Fence::UninitPicture()
{
//...
delete _FencePic;
_FencePic = NULL;
}



class Picture
{
static std::list<Picture*> _img_lst; //List of all the images created. Used for restoration
public:
Picture()
{
Picture::_img_lst.push_back(this); //ERROR
}
};



And make sure that InitPicture() and UninitPicture() are only called once execution of main() has begun.

EDIT: There was only 1 reply when I started this [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Alternately, you could look into singleton methods that would guarantee construction upon use, but in general, if you're doing something that relies on depending on the order of construction of static objects, you might want to rethink your design somewhat.

Actually, I'd recommend against using a singleton. After all, he's bound to want more than one instance of a Picture....

Share this post


Link to post
Share on other sites
Quote:
Original post by joanusdmentia
Umm, that has nothing to do with it... it's because in C++ the construction order of static variables is only defined when the variables are in the same translation unit (.cpp file), and the order in the same translation unit is defined by the order in which they are declared, it has nothing to do with if one instance uses another. Just because the instance of Picture is constructed as _FencePic doesn't mean that the instance of std::list<Picture*> is constructed as _img_list before hand.

I think your best bet here would be to do something like this:

*** Source Snippet Removed ***
And make sure that InitPicture() and UninitPicture() are only called once execution of main() has begun.

EDIT: There was only 1 reply when I started this [smile]


You fixed my problem. You are like a genious or something! I would have never thought of that!!! Thank you so much. When this error showed up, I thought I would never find it. But it works!

Share this post


Link to post
Share on other sites
Quote:
Original post by lzr
You fixed my problem. You are like a genious or something! I would have never thought of that!!! Thank you so much. When this error showed up, I thought I would never find it. But it works!

While this fixes the immediate problem, do keep in mind that as SiCrane suggested you may need to rethink the design. Is every item in you're game going to have a similar structure (do they all have a unique Picture like the Fence)? If so you may want to consider having a class that manages all of the pictures and associates a name with it (this is where you would want to use the Singleton pattern). For example, to get the picture for a Fence you might make a call like this:
PictureManager::GetInstance().GetPicture("Fence");

Share this post


Link to post
Share on other sites

This topic is 4752 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this