C++易错知识点(十一)虚析构函数
2022/1/13 11:33:53
本文主要是介绍C++易错知识点(十一)虚析构函数,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
首先来看这样一个场景,观察构造析构的调用析构顺序。
#include<iostream> using namespace std; class Parent{ private: int a; public: Parent() { cout<<"Parent()"<<endl; } ~Parent() { cout<<"~Parent()"<<endl; } }; class son :public Parent { private: int b; public: son() { cout<<"son()"<<endl; } ~son() { cout<<"~son()"<<endl; } }; int main() { son* p = new son; delete p; return 0; }
最后我们发现构造函数,析构函数的调用是正常情况,符合我们意料之中。
那么现在如果把main()函数当中的son* p = new son;
语句改成Parent* p = new son;
呢?
运行结果如下:
结果我们发现少了son类的析构。
这样肯定是不行的,现在我们来分析背后的原因,好提出解决办法:
1)一个子类的堆对象被父类指针指向了
2)使用delete p内部的工作过程是先调用对应的析构函数。然后释放p申请的内存。即p->Parent();
然后free(p)
分析到这里情况应该比较明确了,因为该子类的堆对象被父类指针指向了,delete时会先调用父类的析构函数,然后直接释放内存,而不会去调用子类析构函数。
解决方法就是将父类子类的析构函数都声明为虚函数
可以看出,虚析构函数可以解决上文发现的问题。事实上将虚构函数声明为虚函数以后,p->Parent()
这一步就变成了虚函数的间接调用,会查找虚表,调用子类对象本身的虚构函数。
这篇关于C++易错知识点(十一)虚析构函数的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享