Jump to content
  • Advertisement
Sign in to follow this  
lzr

C++ Constructor/Static Member Variable Question

This topic is 5055 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
Advertisement
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.

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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!