Search

12.3 — Virtual destructors, virtual assignment, and overriding virtualization

Virtual destructors

Although C++ provides a default destructor for your classes if you do not provide one yourself, it is sometimes the case that you will want to provide your own destructor (particularly if the class needs to deallocate memory). You should always make your destructors virtual if you’re dealing with inheritance. Consider the following example:

Because pBase is a Base pointer, when pBase is deleted, the program looks to see if the Base destructor is virtual. It’s not, so it assumes it only needs to call the Base destructor. We can see this in the fact that the above example prints:

Calling ~Base()

However, we really want the delete function to call Derived’s destructor (which will call Base’s destructor in turn). We do this by making Base’s destructor virtual:

Now this program produces the following result:

Calling ~Derived()
Calling ~Base()

Again, whenever you are dealing with inheritance, you should make your destructors virtual.

Virtual assignment

It is possible to make the assignment operator virtual. However, unlike the destructor case where virtualization is always a good idea, virtualizing the assignment operator really opens up a bag full of worms and gets into some advanced topics outside of the scope of this tutorial. Consequently, we are going to recommend you leave your assignments non-virtual for now, in the interest of simplicity.

Overriding virtualization

Very rarely you may want to override the virtualization of a function. For example, consider the following code:

There may be cases where you want a Base pointer to a Derived object to call Base::GetName() instead of Derived::GetName(). To do so, simply use the scope resolution operator:

You probably won’t use this very often, but it’s good to know it’s at least possible.

The downside of virtual functions

Since most of the time you’ll want your functions to be virtual, why not just make all functions virtual? The answer is because it’s inefficient -- resolving a virtual function call takes longer than a resolving a regular one. Furthermore, the compiler also has to allocate an extra pointer for each class object that has one or more virtual functions. We’ll talk about this more in the next couple of lessons.

12.4 -- Early binding and late binding
Index
12.2 -- Virtual functions

17 comments to 12.3 — Virtual destructors, virtual assignment, and overriding virtualization

  • pranesh

    please have a look at the following code :

    Now this program produces the following result:

    Calling ~Derived()
    Calling ~Base()

    i am unable to understand why 'calling ~Base()' is been printed here?
    when we reached delete pbase; in int main() it goes to Base class first and finds that its destructor is virtual so it goes to Derive class and finds another destructor and executes it but why does it prints ~Base() in any case?

    • jason

      i'm also stuck in the same question!may be when derivative destructor is called,then the cursor returns to base for executing line 31 but it should again call derived destructor as again it will come across the virtual base destructor! someone help please!

    • Gigwig

      That is the thing with Inheritance, constructors are called, by default, from the base class to the derived class and the destructors run from the derived class to the base class.

  • Sakthi

    Hello Alex,
    I assume you must have overloaded the new, delete and paranthesis operators. Could you show the code for this ?
    If not then HOW do these operators work with classes 'Derived' and 'Base' ?
    new int[5] makes sense. but new Derived(5) does not .
    This is driving me nuts. Please help.

  • prags

    HI,
    i wanted to clarify my doubt regarding virtual functions.
    i.e;when v r using the concept of virtual functions,is it necessary dat v shud use d same name for all the functions vich r declared as virtual??especially while showing virtual functions are hierarchical..

  • josabraham

    int main()

    29 {

    30 Derived objDerived ;

    31 Base *pBase = &objDerived ;

    32 delete pBase; //Will call derived and base destructors

    33

    34 return 0;

    35 }

  • Lion

    Really rocking and mind blowing explanation.:D

    Thanks a lot Alex.

  • Mario_G

    Hi Alex,

    I like the "Rule: " part, it's a good reminder
    Maybe some "Tips: " part could be great, like
    "Tips: Whenever you are dealing with inheritance, you should make your destructors virtual."

    I'm going thru you website and taking notes of the "Rules: " and sometimes "Tips: " might be appreciated and easier to find important things to remember or consider.

  • Can you override a virtual function when you have used a pointer instead of a reference?

    EDIT:
    Woops! Yes you can
    Derived cDerived;
    Base *rBase = &cDerived;
    cout << "rBase is a " << rBase->Base::GetName() << endl;

  • Lee

    HI,

    I want to call a derived class function, that isn't defined in the base class, using base class pointers. but this always raises the error:

    error C2039: 'derivedFunctionName' : is not a member of 'BaseClass'

    Do you know how i could get around this?

    Thanks,

    Lee.

    • Add a virtual function of the same name into the base class. You can define the base-class function with an empty body, or even better, make it a pure virtual (abstract) function.

  • Kinten

    I understood it, but I get the feeling that I will forget it really soon, maybe some practice is needed :[
    Well explained, thx

  • sandhya

    Hi Alex,

    In the example for virtual destructor
    class Derived: public Base
    {
    private:
    int* m_pnArray;

    public:
    Derived(int nLength)
    {
    m_pnArray = new int[nLength];
    }

    virtual ~Derived()
    {
    cout << "Calling ~Derived()" << endl;
    delete m_pnArray;
    }
    };

    In the constructor, you have dynamically allocated an integer array using new operator. But in destructor, you have used only "delete m_pnArray;" where u should have used "delete[] m_pnArray;". Correct me if i am wrong.

    • You are correct. This is one of the things I constantly screw up in C++.

      • Ben

        What a stupid mistake, i would never do this. Every child knows, that you have to delete () m_pnArray...
        Damn it, i really did it with this sort of brackets and it was quite confusing, because i didn't see the mistake at first glance.

        • Sorry I know that this is telling me something. I get most of it.

          But at the risk of sounding like a total tool, ok here goes!:

          Why do you need to use a pointer from the base class? This seems to be the main reason we need these virtual functions.

          Why not just use a pointer created from the Derived class?

          Please feel free to call me an idiot, but I'm sure with a good reason for this I'll get it. it just escapes me a bit at the moment. Sorry.

          EDIT:
          Sorry this was supposed to be a stand alone question not a reply to Ben.

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">