Jump to content
  • Advertisement
Sign in to follow this  
fyhuang

[C++] Inheritance not working from constructor?

This topic is 4863 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

Hey all, I'm having this small problem with my code - I have a base Singleton class (not a complete code listing):
class Singleton
{
public:
    void create();
    virtual int init() { return 0; }
    virtual int shutdown() { return 0; }

protected:
    Singleton()
    {
        init();
    }

    virtual ~Singleton()
    {
        shutdown();
    }
};

The purpose of this code is, when the Singleton is created, the init() function is called to perform initialization, and when it is destroyed, the shutdown() function is called to perform shutting-down. Classes that inherit from Singleton can override init() and shutdown(). My problem is - I have a derived class that overrides both init() and shutdown(), but when the Singleton is created, the base Singleton's init() function is called instead of the overridden init() function (obviously I want the overridden one to be called). Not implementing init() and shutdown() in Singleton of course causes the compiler to tell me that, I can't use those functions in the constructor/destructor because they're not defined. Since there's some error-checking code wrapping init() and shutdown() (not shown here), I don't want to copy & paste the constructor code to each derived class. Can anyone help me get this working? Thanks in advance!

Share this post


Link to post
Share on other sites
Advertisement
Won't work. C++ (unlike C#) does not apply the "virtual" to functions called in the constructor/destructor for technical reasons.

Share this post


Link to post
Share on other sites
Hmm. Would it work if I did something like this:


// ...
void create()
{
if ( !ms_Singleton )
{
ms_Singleton = new T(); // Singleton< T > of course
init();
}
}



I figure that that might work for construction, but I still dunno about destruction...

Cheers!

Share this post


Link to post
Share on other sites
Why do you need to do this? What's wrong with just putting the init and shutdown code in the derived class's constructor and destructor? That's what they're for...

Share this post


Link to post
Share on other sites
The only good reason I can think of is that it allows me to handle errors more effectively. Otherwise, yes I suppose I should be just doing it in the constructor [smile].

Thanks and cheers!

Share this post


Link to post
Share on other sites
That will probably work with some small changes:
    class Singleton
{
public:
static void create();
...
};

void Singleton::create()
{
if ( !ms_Singleton )
{
ms_Singleton = new T(); // Singleton< T > of course
ms_Singleton->init();
}
}
create() needs to be static so that you can call it without already having an instance of the class. There is probably no need make shutdown() virtual because with a virtual destructor, all the destructors are called.

Share this post


Link to post
Share on other sites
Quote:
Original post by fyhuang
Hey all,

I'm having this small problem with my code - I have a base Singleton class (not a complete code listing):

*** Source Snippet Removed ***

The purpose of this code is, when the Singleton is created, the init() function is called to perform initialization, and when it is destroyed, the shutdown() function is called to perform shutting-down. Classes that inherit from Singleton can override init() and shutdown().

My problem is - I have a derived class that overrides both init() and shutdown(), but when the Singleton is created, the base Singleton's init() function is called instead of the overridden init() function (obviously I want the overridden one to be called).

Not implementing init() and shutdown() in Singleton of course causes the compiler to tell me that, I can't use those functions in the constructor/destructor because they're not defined. Since there's some error-checking code wrapping init() and shutdown() (not shown here), I don't want to copy & paste the constructor code to each derived class.

Can anyone help me get this working? Thanks in advance!



Because in ctor the vtable slots not being completely setup yet,and in dtor,the vtable is restored back...
So,calling of init or shutdown is the CSingleton::init and CSingleton::shutdown,not any inheritance version...

Share this post


Link to post
Share on other sites
Quote:
Original post by Andrew Russell
The reason for why this happens is described in detail here along with several possible workarounds (some of which have already been posted).

Thanks for that. I picked up a useful peice of know-how from that article I wasn't aware of.

Share this post


Link to post
Share on other sites
In C++, an object of a derived class is progressively constructed.

Suppose you have class Base and derive from it, class Derived.

C++ first calls Base's constructor. If this contains virtual functions, they are not yet overridden, because at this point, the object is still a "Base" object (in fact, it's not really even that yet, it's partially complete).

Once the "Base" constructor is called, then the Derived constructor is called. At this point, the object has become (a partially constructed) a Derived. Therefore overridden virtual functions called *now*, will call Derived's ones.

If Derived's constructor throws an exception, Base's destructor will be called, but Derived's won't be (as it isn't yet *fully* constructed).

It all makes perfect sense - you *cannot* call a class's methods before its base class has been constructed - as they might in turn call methods of the base class which relied on private members of the base class which weren't assigned their right values yet, which would break (obviously).

(Note that this is different from Java, where you *can* do this, although it still doesn't make very much sense, and some people view it as a bug)

---

You might do better making Singleton a template class rather than a base class for your objects stored in it.

Mark

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!