A C++ class containing virtual member functions has a non-virtual destructor.
Since this class has virtual member functions, it will be used as a base class. The use of non-virtual destructors in base classes is dangerous because it can cause objects to be torn down incorrectly. The example below illustrates the problem.
The only good choices for base class destructors is public virtual or protected virtual. A protected non-virtual destructor is just as bad as a public non-virtual destructor; the only difference is that the bad thing happens only inside the member functions of the derived class.
Marking a destructor as protected makes it impossible to delete instances of that class. This is desirable when implementing an object that wants to control its own lifetime, for example by reference counting. In almost all other cases, a public virtual destructor is the right choice.
ID |
Observation |
Description |
---|---|---|
1 |
Definition |
This shows where the class was defined |
#include <stdio.h> #include <string.h> #include <stdlib.h> class evil { public: ~evil() {} // bad: should be virtual virtual void say_hi() { printf("I am evil\n"); } }; // class with a non-trivial destructor class victim : public evil { protected: char * m_string; public: victim() { m_string = new char[40]; } ~victim() { delete m_string; } // copy constructor victim::victim(const victim & source) : m_string(new char[40]) { for (int i = 0; i < 40; i++) { m_string[i] = source.m_string[i]; } } // assignment operator victim& victim::operator=(const victim & source) { for (int i = 0; i < 40; i++) { m_string[i] = source.m_string[i]; } return *this; } }; int main(int argc, char **argv) { evil* p = new victim(); // allocates m_string p->say_hi(); delete p; // Calls ~evil, but not ~victim because ~evil is not virtual // therefore m_string is never freed };
Copyright © 2010, Intel Corporation. All rights reserved.