virtual destructor

class Base
{
public:
virtual ~Base()
{
cout << "Calling ~Base()" << endl;
}
};

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;
}
};

int main()
{
Derived *pDerived = new Derived(5);
Base *pBase = pDerived;
delete pBase;

return 0;
}
// i just want to know that i am calling to base destructor here then why it is calling drive destructor also ?
You call the destructor of the object pointed to by pBase. That object has type Derived. Derived has virtual destructor and therefore you do call the Destructor::~Destructor just like you should. It would be an error to not call it.
i cant understand
The destructor is virtual. That means that instead of resolving call statically (calling whichever function correspond to pointer type) it resolves it dinamically: though hidden member in class it selects function corresponding to real type of class pointer is pointing to.
So ~Derived is executed. Destructors of the derived classes call destructors of base class after they finished. So you will see
Calling ~Derived()
Calling ~Base()
in the output.
so you are saying that here the virtual concept is working
so it invoke to drive class destructor first




but as we know that always that drive class destructor invoke first then base class destructor invoke so base destructor exicute second
so here two concepts work together
i m right or wrong ?
Last edited on
Yes. two concepts at work:
1) Destructors are called from most derived to base
2) Virtual calls call functions corresponding to real type of object, not type of pointer/reference.
thanks guys
You might be mixing two things. The virtual function system does select during runtime which function is called, but what that function does is an another matter.


Here is a simple case to show what the function does:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
using std::cout;

class Base
{
public:
  Base() { cout << "Calling Base()\n"; }
  ~Base() { cout << "Calling ~Base()\n"; }
};

class Derived : public Base
{
public:
  Derived() { cout << "Calling Derived()\n"; }
  ~Derived() { cout << "Calling ~Derived()\n"; }
};

class Bar : public Derived
{
public:
  Bar() { cout << "Calling Bar()\n"; }
  ~Bar() { cout << "Calling ~Bar()\n"; }
};

int main()
{
  Bar foo;
  cout << "Hello\n";
  return 0;
}

The construction and destruction of derived class objects has its rules.
thanks buddy for your example
The virtual destructor, however, is the more interesting case.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
using std::cout;

class Base
{
public:
  Base() { cout << "Calling Base()\n"; }
  /* virtual */ ~Base() { cout << "Calling ~Base()\n"; }
};

class Derived : public Base
{
public:
  Derived() { cout << "Calling Derived()\n"; }
  ~Derived() { cout << "Calling ~Derived()\n"; }
};

class Bar : public Derived
{
public:
  Bar() { cout << "Calling Bar()\n"; }
  ~Bar() { cout << "Calling ~Bar()\n"; }
};

int main()
{
  Base* foo = new Bar;
  cout << "Hello\n";
  delete foo;
  return 0;
}


Notice in line 27 I made foo a pointer to the base class, but instantiated an object of the derived class "Bar". By changing the destructor in line 8 from virtual to non-virtual, the behavior of the delete in line 29 changes. With a virtual destructor, the destructor chain beginning at Bar is called. Without the virtual destructor, only the "Base" constructor is called.
Lets pretend that the class hierarchy is a house. Base is the roof, Derived is the walls of the rooms, and Bar is the furniture.

Create a Bar:
1. Hoist the roof.
2. Add the walls.
3. Place the chairs.

Remove Bar (virtual):
1. Take out the furniture.
2. Remove (internal) walls.
3. Demolish the roof.
The house is no more.

Remove Base, non-virtual:
1. Demolish the roof.
The house is no more?
Just to clean up your analogy a little bit...

The base class would be RoofedStructure. It's constructor puts up a roof.
The intermediate class would be House. A House is a RoofedStructure, and its constructor first calls the RoofedStructure constructor and then adds walls.
The bottom class would be FurnishedHouse. A FurnishedHouse is a House that contains furniture. The constructor first calls the House constructor and then adds furniture.

That being said, your conclusion is CORRECT. This is why it is critical to make destructors virtual in classes that are intended to be base classes. If the base class has a non-virtual destructor and the derived classes have resources that need to be cleaned up, if you delete a pointer to the base class, the derived class resources will not get cleaned up properly.

Edit: Fixed it's/its typo.
Last edited on
Topic archived. No new replies allowed.