基类与接口类中的虚析构函数(virtual destructor)
开门见山,摆结论:
接口类和基类的一定要有虚析构函数;
一般情况下,在基类或者接口类中添加虚析构函(virtual destructor)数非常重要。原因很简单,就是想让析构的顺序从继承类开始往上开始一步步析构直到基类。
看例子吧:
首先,接口类不写虚析构函数
// virtual d'tor // In base class or interface, it is important that add a virtual destructor class IFoo { public: virtual void dosomething() = 0; }; class Foo : public IFoo { public: Foo(int* pInt = NULL) : pInt(pInt){} virtual void dosomething() { pInt = new int[10]; pInt[1] = 1; pInt[2] = 2; } ~Foo() { delete[] pInt; } int* get_pInt() { return pInt; } const int* get_pInt() const { return pInt; } private: int* pInt; }; 去调用测试一下: using namespace std; int main() { IFoo* f = new Foo(); f->dosomething(); delete f; return 0; }
当执行
delete f;
时,程序并不会调用Foo类中的析构函数(因为你没在基类中写虚析构函数),所以造成内存泄露。
下面我们加上virtual destructor
class IFoo { public: virtual void dosomething() = 0; virtual ~IFoo(){} // add virtual destructor }; class Foo : public IFoo { public: Foo(int* pInt = NULL) : pInt(pInt){} virtual void dosomething() { pInt = new int[10]; pInt[1] = 1; pInt[2] = 2; } ~Foo() { delete[] pInt; } int* get_pInt() { return pInt; } const int* get_pInt() const { return pInt; } private: int* pInt; }; using namespace std; int main() { IFoo* f = new Foo(); f->dosomething(); delete f; // It's ok!!! return 0; }
所以结论是,接口类和基类的一定要有虚析构函数;