Problem
Why does a destructor in base class need to be declared virtual?
Follow up - Is it always required for base class to have virtual destructors?
Solution
You want them to be virtual so that all subclass destructors are automatically called when the object is destroyed, even if it is destroyed through a pointer to the base class.Calling a method with an object pointer always invokes:
- the most derived class function, if a method is virtual.
- the function implementation corresponding to the object pointer type (used to call the method), if a method is non-virtual.
When any derived class object goes out of scope, the destructor of that derived class gets called first. It then calls its parent class destructor so memory allocated to the object is properly released.
But, if we call delete on a base pointer which points to a derived class object, the base class destructor gets called first (for non-virtual function). For example:
class Base { public: Base() { cout << "Base Constructor " << endl; } ~Base() { cout << "Base Destructor " << endl; } /* see below */ }; class Derived: public Base { public: Derived() { cout << "Derived Constructor " << endl; } ~Derived() { cout << "Derived Destructor " << endl; } }; void main() { Base *p = new Derived(); delete p; }
Output
Base Constructor Derived Constructor Base Destructor
If we declare the base class destructor as virtual, this makes all the derived class destructors virtual as well. If we replace the above destructor with:
virtual ~Base() { cout << "Base Destructor" << endl; }
Then the output becomes:
Base Constructor Derived Constructor Derived Destructor Base Destructor
So we should use virtual destructors if we call delete on a base class pointer which points to a derived class.
Follow up question - Is it always required for base class to have virtual destructor. Answer is no.
As described by Johannes here, applying virtual to base class would make it impossible to apply the empty base class optimization, and could multiply the size of classes up to 16 times than what it would be without
virtual
on common platforms.A
virtual
destructor is needed when you delete
an object whose dynamic type is DerivedClass
by a pointer that has type BaseClass*
. The virtual
makes the compiler associate information in the object making it able to execute the derived class constructor. Missing the virtual
in such cases causes undefined behavior.If you don't need this, and your class is only used as a base class, it's best to make the destructor
protected
, thus preventing that users accidentally delete
in the described way. For more clarity see Virtuality, specifically, "Guideline #4: A base class destructor should be either public and virtual, or protected and nonvirtual."References
http://tianrunhe.wordpress.com/2012/04/13/destructor-in-base-class-needed-to-be-virtual-in-c/
http://stackoverflow.com/questions/5873515/why-should-the-destructor-of-base-classes-be-virtual
0 comments:
Post a Comment