Jump to content
  • Advertisement
Sign in to follow this  
luasitdown

what is different between destructor and virtual destructor?

This topic is 4844 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!