what is different between destructor and virtual destructor?

Started by
4 comments, last by nmi 18 years, 8 months ago
Give me simple class to clarify please
Advertisement
A class is really not necessary to explain this. A normal destructor is set to be just that a normal destructor that the class has implementation for and nowhere else. A virtual destructor can be customized for the task at hand because it can be overriden. So if anywhere you need to change the behavior of the destructor you should make it virtual.
My JournalComputer science education cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody an expert painter. (Eric Raymond)"C makes it easy to shoot yourself in the foot. C++ makes itharder, but when you do, it blows away your whole leg."-- Bjarne Stroustrup
If you inherit from a class that doesn't have a virtual destructor then when your derived class gets deleted or goes out of scope the memory in the derived class will not be deleted. The virtual keyword means that when a function is overridden in the derived class, the derived classes function will be called instead of the base classes function.

That's how i understand it.

ace
Neither of the above explanations are completely correct.

Virtual destructors are important when using inheritance. Destructors are chained together. After a class's destructor is executed, the destructor of the class it is derived from is executed. This continues until the constructor for the base class is executed. Now, when an object with a virtual destructor is destroyed, the destructor in the most derived class is called first (just like any virtual function). If the destructor of the base class is not virtual, then the destructor of the class that is being destroyed is called first, not the most derived class. This becomes a problem when you delete an object using a pointer to its base class. Here's an example:
	struct A            { ~A() { cout << "~A() "; } };	struct B : public A { ~B() { cout << "~B() "; } };	struct C : public B { ~C() { cout << "~C() "; } };	A * a = new C;	B * b = new C;	C * c = new C;	cout << endl << "deleting a: ";    delete a;	cout << endl << "deleting b: ";    delete b;	cout << endl << "deleting c: ";    delete c; 
This code produces the following output:
    deleting a: ~A()    deleting b: ~B() ~A()    deleting c: ~C() ~B() ~A() 
Notice how even though all the classes are instances of C, only when C is deleted directly is its destructor called. The solution is to make the base destructor virtual:
	struct X            { virtual ~X() { cout << "~X() "; } };	struct Y : public X {         ~Y() { cout << "~Y() "; } };	struct Z : public Y {         ~Z() { cout << "~Z() "; } };	X * x = new Z;	Y * y = new Z;	Z * z = new Z;	cout << endl << "deleting x: ";    delete x;	cout << endl << "deleting y: ";    delete y;	cout << endl << "deleting z: ";    delete z; 
This code produces the following output:
    deleting x: ~Z() ~Y() ~X()    deleting y: ~Z() ~Y() ~X()    deleting z: ~Z() ~Y() ~X() 
Notice that no matter which class the pointer points to, all the destructors are called.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
I found an example that shows the difference between virtual and non virtual destructors:

#include <iostream>

using namespace std;

class Base
{
public:
Base(){ cout<<"Constructor: Base"<<endl;}
~Base(){ cout<<"Destructor : Base"<<endl;}
};


class Derived: public Base
{
public:
Derived(){ cout<<"Constructor: Derived"<<endl;}
~Derived(){ cout<<"Destructor : Derived"<<endl;}
};


void main()
{
Base *Var = new Derived();
delete Var;
}

----------------------------------
Output:
Constructor: Base
Constructor: Derived
Destructor : Base
----------------------------------


#include <iostream>

using namespace std;

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


class Derived: public Base
{
public:
Derived(){ cout<<"Constructor: Derived"<<endl;}
~Derived(){ cout<<"Destructor : Derived"<<endl;}
> };


void main()
{
Base *Var = new Derived();
delete Var;
}

----------------------------------
Output:
Constructor: Base
Constructor: Derived
Destructor : Derived
Destructor : Base
----------------------------------

If you delete an object using its base class pointer, the base class must have a virtual destructor in order to execute the derived class destructor. If the base class destructor is non virtual, the derived class destructor is never executed.
Lord CiriuzAquadize Studios
There is a third form of destructor involved, when using a virtual base class:

class A;
class B1 : virtual public A ...;
class B2 : virtual public A ...;
class C : public B1, public B2 ...;

Here the destructor of A should be called only once, so the compiler must generate different code for this case.

This topic is closed to new replies.

Advertisement