What is a virtual destructor and when would you use one?
Last edited by TopGun; 20th April 2010 at 19:01.
- A virtual destructor is a class' destructor conforming to the C++'s polymorphism mechanism; by declaring the destructor virtual you ensure it is placed in the VTABLE of the class and it will be called at proper times
- You make a class' destructor virtual to ensure proper clean-up when the class is supposed to be subclassed to form a hierarchy and you want to delete a derived object thorough a pointer to it (the base class)
- E.g. :
What will happen in our rather lengthy example? Everything seems OK and most of the available C++ compilers will not complain about anything (*). Nevertheless there is something pretty wrong here. The C++ standard is clear on this topic: when you want to delete a derived class object through a base class pointer and the destructor of the base class is not virtual the result is undefined. That means you're on your own from there and the compiler won't help you! What is the most often behavior in such situations is that the derived class' destructor is never called and parts of your derived object are left undestroyed. In the example above you will leave behind a memory leak, the m_charCodes member will not be destroyed because the destructor ~Derived() will not be calledCode:#include <vector> #include <iostream> using namespace std; class Base { public: Base(const char* name); // warning! the destructor should be virtual ~Base(); virtual void doStuff(); private: const char* m_name; }; Base :: Base(const char* name) : m_name(name) { } Base :: ~Base() { } void Base :: doStuff() { cout << "Doing stuff in Base" << endl; } class Derived : public Base { public: Derived(const char* name); ~Derived(); virtual void doStuff(); private: vector<int>* m_charCodes; }; Derived :: Derived(const char* name) : Base(name) { m_charCodes = new vector<int>; } Derived :: ~Derived() { delete m_charCodes; } void Derived :: doStuff() { cout << "Doing stuff in Derived" << endl; } int main(int argc, char* argv[]) { // assign the derived class object pointer to // the base class pointer char* theName = "Some fancy name"; Base* b = new Derived(theName); // do some computations and then delete the // pointer delete b; return 0; }
- A thing to notice is that declaring all destructors virtual is also pretty inefficient and not advisable. That makes sense (declaring the destructor virtual) only if your class is supposed to be part of a hierarchy as a base class, otherwise you'll just waste memory with the class' vtable generated only for the destructor. So declare a virtual destructor in a class "if and only if that class is part of a class hierarchy, containing at least one virtual function. In other words, it is not necessary for the class itself to have that virtual function - it is sufficient for one of its descendents to have one."
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks