[ACCEPTED]-Does delete on a pointer to a subclass call the base class destructor?-base-class

Accepted answer
Score: 188

The destructor of A will run when its lifetime 14 is over. If you want its memory to be freed 13 and the destructor run, you have to delete 12 it if it was allocated on the heap. If it 11 was allocated on the stack this happens 10 automatically (i.e. when it goes out of 9 scope; see RAII). If it is a member of 8 a class (not a pointer, but a full member), then 7 this will happen when the containing object 6 is destroyed.

class A
{
    char *someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { delete[] someHeapMemory; }
};

class B
{
    A* APtr;
public:
    B() : APtr(new A()) {}
    ~B() { delete APtr; }
};

class C
{
    A Amember;
public:
    C() : Amember() {}
    ~C() {} // A is freed / destructed automatically.
};

int main()
{
    B* BPtr = new B();
    delete BPtr; // Calls ~B() which calls ~A() 
    C *CPtr = new C();
    delete CPtr;
    B b;
    C c;
} // b and c are freed/destructed automatically

In the above example, every 5 delete and delete[] is needed. And no delete 4 is needed (or indeed able to be used) where 3 I did not use it.

auto_ptr, unique_ptr and shared_ptr etc... are great 2 for making this lifetime management much 1 easier:

class A
{
    shared_array<char> someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { } // someHeapMemory is delete[]d automatically
};

class B
{
    shared_ptr<A> APtr;
public:
    B() : APtr(new A()) {}
    ~B() {  } // APtr is deleted automatically
};

int main()
{
    shared_ptr<B> BPtr = new B();
} // BPtr is deleted automatically
Score: 32

When you call delete on a pointer allocated 2 by new, the destructor of the object pointed 1 to will be called.

A * p = new A;

delete p;    // A:~A() called for you on obkect pointed to by p
Score: 22

It is named "destructor", not "deconstructor".

Inside 10 the destructor of each class, you have to 9 delete all other member variables that have 8 been allocated with new.

edit: To clarify:

Say 7 you have

struct A {}

class B {
    A *a;
public:
    B () : a (new A) {}
    ~B() { delete a; }
};

class C {
    A *a;
public:
    C () : a (new A) {}        
};

int main () {
    delete new B;
    delete new C;
}

Allocating an instance of B and 6 then deleting is clean, because what B allocates 5 internally will also be deleted in the destructor.

But 4 instances of class C will leak memory, because 3 it allocates an instance of A which it does 2 not release (in this case C does not even 1 have a destructor).

Score: 5

If you have a usual pointer (A*) then the 5 destructor will not be called (and memory 4 for A instance will not be freed either) unless 3 you do delete explicitly in B's destructor. If 2 you want automatic destruction look at smart 1 pointers like auto_ptr.

Score: 4

You should delete A yourself in the destructor 1 of B.

Score: 4
class B
{
public:
    B()
    {
       p = new int[1024];  
    }
    virtual ~B()
    {
        cout<<"B destructor"<<endl;
        //p will not be deleted EVER unless you do it manually.
    }
    int *p;
};


class D : public B
{
public:
    virtual ~D()
    {
        cout<<"D destructor"<<endl;
    }
};

When you do:

B *pD = new D();
delete pD;

The destructor will be called 9 only if your base class has the virtual 8 keyword.

Then if you did not have a virtual 7 destructor only ~B() would be called. But 6 since you have a virtual destructor, first 5 ~D() will be called, then ~B().

No members 4 of B or D allocated on the heap will be 3 deallocated unless you explicitly delete 2 them. And deleting them will call their 1 destructor as well.

Score: 1

You have something like

class B
{
   A * a;
}
B * b = new B;
b->a = new A;

If you then call 12 delete b;, nothing happens to a, and you have a memory 11 leak. Trying to remember to delete b->a; is not a good 10 solution, but there are a couple of others.

B::~B() {delete a;}

This 9 is a destructor for B that will delete a. (If 8 a is 0, that delete does nothing. If a 7 is not 0 but doesn't point to memory from 6 new, you get heap corruption.)

auto_ptr<A> a;
...
b->a.reset(new A);

This way you 5 don't have a as a pointer, but rather an 4 auto_ptr<> (shared_ptr<> will do as 3 well, or other smart pointers), and it is 2 automatically deleted when b is.

Either of 1 these ways works well, and I've used both.

Score: 1

I was wondering why my class' destructor 5 was not called. The reason was that I had 4 forgot to include definition of that class 3 (#include "class.h"). I only had a declaration 2 like "class A;" and the compiler was happy 1 with it and let me call "delete".

Score: 0

No. the pointer will be deleted. You should 2 call the delete on A explicit in the destructor 1 of B.

Score: 0

The destructor for the object of class A 5 will only be called if delete is called 4 for that object. Make sure to delete that 3 pointer in the destructor of class B.

For 2 a little more information on what happens 1 when delete is called on an object, see: http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.9

Score: 0

no it will not call destructor for class 3 A, you should call it explicitly (like PoweRoy 2 told), delete line 'delete ptr;' in example 1 to compare ...

  #include <iostream>

  class A
  {
     public:
        A(){};
        ~A();
  };

  A::~A()
  {
     std::cout << "Destructor of A" << std::endl;
  }

  class B
  {
     public:
        B(){ptr = new A();};
        ~B();
     private:
        A* ptr;
  };

  B::~B()
  {
     delete ptr;
     std::cout << "Destructor of B" << std::endl;
  }

  int main()
  {
     B* b = new B();
     delete b;
     return 0;
  }

More Related questions