4
votes

I am trying the following example:

class base // base class
{
public:
    std::list<base*> values;
    base(){}
    void initialize(base *b) {
        values.push_front(b);
    }
    virtual ~base()
    {
        values.clear();
        cout<<"base called"<<endl;
    }
};

class derived : public base // derived class
{
public:
    ~derived(){
        cout<<"derived called"<<endl;
    }

};

int main()
{
    derived *d = new derived;
    base *b = new base;
    b->initialize(static_cast<base *>(d)); /* filling list */
    delete b;
    return 0;
}

Q.1) Why does destructor of derived class not get called, as in base class destructor I am performing values.clear()?

Q.2) Is derived class destructor definition required if base class destructor is virtual?

4
The derived class destructor is not called because you never delete the object! - Bo Persson

4 Answers

7
votes

Q1. Because you're not deleting an object of type derived. You only do delete b;, which deletes a base. You should also call delete d;.

Also, you should specify what object is responsible for memory management. Your design is prone to error. You're better off using a smart pointer to prevent ambiguity. Also, to behave as you expect it, the destructor should be:

virtual ~base()
{
    for ( int i = 0 ; i < values.size() ; i++ )
        delete values[i];
    values.clear();
    cout<<"base called"<<endl;
}

Of course, with this approach, it would be undefined behavior calling delete d; in your main.

Q2. No, the definition is not required.

4
votes

Why does destructor of derived class is not getting called, as in base class destructor I am performing values.clear();

values.clear() removes all the pointers from this list. It does not delete the objects being pointed to; that would be extremely dangerous, since the list has no way of knowing whether it's responsible for their lifetime, or whether they are just being used to refer to objects managed elsewhere.

If you want the list to own the objects, then you must either delete them yourself when removing them, or store smart pointers such as std::unique_ptr<base>. If your compiler doesn't support the new smart pointers, then you might find Boost's Pointer Container library useful.

Does derived class destructor definition is required. If base class destructor is virtual.

It's only needed if there is something in the derived class that needs cleaning up. There's no need to define an empty one if there's nothing for it to do.

1
votes

You don't actually delete d, so of course the destructor is not being called. Either make d statically allocated (derived d instead of derived *d = new derived) or call delete d.

If you don't declare the destructor in the derived class a default one will be created. The base class destructor will still be called, see the FAQ (11.12). Note also that since the base class destructor is virtual, the derived class destructor is automatically virtual (whether you define one or not), see FAQ (20.7).

0
votes

Why do you think the destructor of derived class should be called? You only delete base and it is an instance of the base class.

No the definition of the destructor is not required - you may ommit it.