本来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删除一个对象的时候,你才需要定义虚的析构函数.
看下面的代码段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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; } |
一切都工作得很好,直到有一天,你学习了设计模式,明白我们要面向接口编程,而不是面向实现编程.于是代码改成这样:
1 2 3 4 5 6 | int main(){ Base* d = new Derived(11); d->doSomeThing(); delete d; } |
于是问题来了,delete的时候是要调用析构函数的,可是我们的析构函数不是虚函数,于是只会调用Base的析构函数
这样派生类就析构不完全,程序里隐含了bug.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步