Jump to content
  • Advertisement
Sign in to follow this  
?????????????????

virtual and class inherience

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

Hello there dear forum.

 

So my question is about class inheriences and virtual functions.

 

so lets say I got a class structure as following

class A{

A();
~A();

virtual void f(){ //does w/e }

};

class B : public A{

B();
~B();
void f(){ //does something diffrent }
};

main(){

B object;
}

so first thing is, in what order do constructers/deconstructers get called :o ? As far as I understand the constructurs are builed from the base up meaning the constructor of A will get called and then the constructor of B and deconstructers are the opposite, meaning B's deconstructor first and then A's. Am I right o.o ?

The main question tho once I "overload" the virtual function in the child class does the base's class function still get called or only the function in B. ( once I actually call the function ofc).

 

P.S all under the asumption I am creating only a object of B and no objects of A are used.

 

Thanks in advance ^^ <3

Share this post


Link to post
Share on other sites
Advertisement

Think of it like a stack of plates.  Say you have plates, A, B and C.

 

As they are constructed, they are made into a stack.  So A, then B, then C.

 

Now as you remove them ( destructor ) from the stack of plates, the destructors are called in reverse order, so C, then B, then A.

 

So, constructors are called from the base class and up the inheritance tree.  Destructors are called in reverse order, from the most inherited up to the base.

 

In the event of multiple inheritance, the order they are declared determines order.

 

so say:

 

class C : public A, B {}

 

A's constructor, then B's are called, while during destruction, B's is called first, then A.

 

Remember to mark all destructors as virtual or the base class destructors will not be called.

Edited by Serapth

Share this post


Link to post
Share on other sites

Remember to mark all destructors as virtual or the base class destructors will not be called.

That's not quite right. The destructors for any base classes will always be called as part of a derived class' destructor. What you are thinking about is deleting a derived class through a base class pointer. If the destructor is not virtual in that case what will happen is the derived class destructor will not be called, but the base class destructor will be (as well as possibly an incorrect size being passed to the memory deallocation function).

Regarding the bodies of virtual functions: Under normal circumstances, if B overrides a virtual function in A, then only the body of B's version will be run unless you explicitly call A's version. However, if you call the virtual function inside A's constructor or destructor then A's version will be called.

Share this post


Link to post
Share on other sites

 

Remember to mark all destructors as virtual or the base class destructors will not be called.

That's not quite right. The destructors for any base classes will always be called as part of a derived class' destructor. What you are thinking about is deleting a derived class through a base class pointer. If the destructor is not virtual in that case what will happen is the derived class destructor will not be called, but the base class destructor will be (as well as possibly an incorrect size being passed to the memory deallocation function).

 

Yes, my bad, I should have been more explicit.  The first part I hold true though, if you have a class that will ever be derived from, you should mark the destructor as virtual.  I should have said may not be called however, or gone into more detail.

Share this post


Link to post
Share on other sites

Thanks alot for the answer guys really cleared thigns up they were really helpful :o ! 

 

Now I just have 1 follow up question, if I dont overide the virtual f() function in my child class, can I still call the original f() function ( defined in the base class ) through my child object ( the B object in my example )

Share this post


Link to post
Share on other sites

As soon as you mark a method virtual in C++ it will stay virtual from that point onwards, a destructor is just another method as virtual is concerned. You shouldn't ever call virtual functions in a constructor or destructor as the dispatch might not be correct for what you want it to do.

Share this post


Link to post
Share on other sites

You can make a non-virtual call from within a virtual function though which is sometimes needed (not for destructors though, which automatically call the base class destructors)

 

e.g.

class Base
{
public:
    virtual void f() { cout << "Base::f" << endl; }
};

class Derived : public Base
{
public:
    void f() // is still virtual
    {
        cout << "Derived::f" << endl;
        Base::f();  // call base class implementation from derived class explicitly
    }
};

Share this post


Link to post
Share on other sites

 

You can make a non-virtual call from within a virtual function though which is sometimes needed (not for destructors though, which automatically call the base class destructors)

 

e.g.

class Base
{
public:
    virtual void f() { cout << "Base::f" << endl; }
};

class Derived : public Base
{
public:
    void f() // is still virtual
    {
        cout << "Derived::f" << endl;
        Base::f();  // call base class implementation from derived class explicitly
    }
};

That was hell of useful as well, thanks so much for the tip :o !

Share this post


Link to post
Share on other sites

You shouldn't ever call virtual functions in a constructor or destructor as the dispatch might not be correct for what you want it to do.

Unless, of course, static dispatch is what you want it to do.  It's simple enough to understand that constructors and destructors treat all calls to their own member functions as non-virtual.

 

For the curious, here's why:  To help ensure that member functions are only being called on initialized objects in valid states, C++ has a guiding principle that no class member function should be called before the constructor of the class is called or after the destructor of the class has run. 

 

During execution of a base class constructor, the derived class constructor has not yet been called, and during execution of a base class destructor, the derived class destructor has already been run.  So it would be a violation of the above principle if the base class constructor or destructor could call any derived class members.

 

Virtual function calls would allow exactly that, so within constructors and destructors, calls to the object's member functions are all treated as non-virtual.

 

The way I like to think of it is that during execution of a base class constructor, the object being constructed is not yet a derived type object.  The derived class's constructor has not yet been called and so the derived class's functions are not yet accessible.  Similarly, during execution of a base class destructor, the object being destructed is no longer a derived type object.  The derived class's destructor has already run and so the derived class's functions are no longer accessible.

Edited by VReality

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!