C++ Constructor/Static Member Variable Question

Started by
7 comments, last by joanusdmentia 19 years, 4 months ago
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?
------------------------My Site: http://lzr.cc
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.
Rob Loach [Website] [Projects] [Contact]
I don't think you understand. Fence is not derived from Picture or vise versa
------------------------My Site: http://lzr.cc
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.
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 restorationpublic:    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]
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
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....
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
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!
------------------------My Site: http://lzr.cc
Ahhh, I understand what you're getting at now.

... Although I was a little too late [smile].
Rob Loach [Website] [Projects] [Contact]
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");
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V

This topic is closed to new replies.

Advertisement