本来C++继承机制已经保证了构造和析构过程都会自动调用基类的对应部分的
class Base
{
public:
~Base(){
cout << "destructor Base" << endl;
}
};
class Derived:public Base
{
};
int main()
{
Derived *d = new Derived;
delete d;
return 0;
}
问题在于delete的时候d的静态类型和动态类型是一致的,但是有时候如果不一致,编译器无法在没有虚函数机制的帮助下调用正确的析构函数
并不是所有的类都要定义虚的析构函数.因为在C++中引入虚函数是有代价的.
只要当你需要通过delete ptr删除一个对象的时候,你才需要定义虚的析构函数.
看下面的代码段:
class Base{ public: Base(int i):m(i){} virtual void doSomeThing()=0; private: int m; }; class Derived:public Base{ public: Derived(int v):Base(v){} void doSomeThing(){ } }; int main(){ Derived* d = new Derived(11); d->doSomeThing(); delete d; }
一切都工作得很好,直到有一天,你学习了设计模式,明白我们要面向接口编程,而不是面向实现编程.于是代码改成这样:
int main(){ Base* d = new Derived(11); d->doSomeThing(); delete d; }
于是问题来了,delete的时候是要调用析构函数的,可是我们的析构函数不是虚函数,于是只会调用Base的析构函数
这样派生类就析构不完全,程序里隐含了bug.