在看《C++沉思录》的时候,看到这段话:

2018版-第4章-类设计者的核查表-第40页
什么时候类需要虚析构函数?
1.不会用作基类的类是不需要虚析构函数。
2.如果会使用基类指针并delete,那么需要使用虚析构函数,即使类里没有任何成员函数,否则delete会产生内存泄漏

书里提到的这件事情我之前没有注意过,于是写了测试代码如下:

class A {int a;
};class B : public A {int b;
};int main() {A *a = new B();delete a;return 0;
}

上面的代码会造成内存泄漏:

-> % g++ -fsanitize=address test.cpp
-> % ./a.out
=================================================================
==25445==ERROR: AddressSanitizer: new-delete-type-mismatch on 0x602000000010 in thread T0:object passed to delete has wrong type:size of the allocated type:   8 bytes;size of the deallocated type: 4 bytes.#0 0x7f901bc429d8 in operator delete(void*, unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe19d8)#1 0x562ecf25d92c in main (/home/ubuntu/a.out+0x92c)#2 0x7f901b791b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)#3 0x562ecf25d7a9 in _start (/home/ubuntu/a.out+0x7a9)0x602000000010 is located 0 bytes inside of 8-byte region [0x602000000010,0x602000000018)
allocated by thread T0 here:#0 0x7f901bc41458 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0458)#1 0x562ecf25d89b in main (/home/ubuntu/a.out+0x89b)#2 0x7f901b791b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)SUMMARY: AddressSanitizer: new-delete-type-mismatch (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe19d8) in operator delete(void*, unsigned long)
==25445==HINT: if you don't care about these errors you may set ASAN_OPTIONS=new_delete_type_mismatch=0
==25445==ABORTING

报错中说明是new-delete-type-mismatch,分配了8字节,结果只删除了4字节,明显的内存泄漏。


有了虚析构函数后,delete操作会正确识别类的真正类型,从而不会删除错误。

C++的类什么时候需要虚析构函数相关推荐

  1. 微信小程序服务类目大坑:特殊行业服务类目所需资质材料

    作为一个技术开发人员,遇到特殊行业服务类目所需资质材料,只能叫苦连天了,妈的,这个不是技术可以解决的问题,如果技术可以解决的问题都不是问题. 百牛信息技术bainiu.ltd整理发布于博客园 特殊行业 ...

  2. C++类继承时构造函数与析构函数的执行顺序

    C++类继承时构造函数与析构函数的执行顺序 在C++类中,类A继承类B时,如果创建一个A的对象时,会首先调用基类的构造函数,再调用派生类的构造函数,而析构函数的执行相反,但是当基类和派生类分别有一个成 ...

  3. 类String的构造函数、析构函数和赋值函数

    一.类String的原型为: 1 class String 2 { 3 public: 4 String(const char *str = NULL); //普通构造函数 5 6 ~String(v ...

  4. 实验3.1 定义一个CPU类,观察构造函数和析构函数的调用顺序

    题目 定义一个CPU类,包含等级(rank).频率(frequency).电压(voltage)等属性,有两个公有成员函数run.stop.其中,rank为枚举类型CPU_Rank,定义为enum C ...

  5. php类中的构造函数与析构函数

    1.php类中的构造函数 a.构造函数的定义及创建 构造函数的英文是constructor,通常是和析构函数配合使用的. 所谓构造函数,就是在我们这个类运行之初需要初始的东东,执行类中所有方法之前,无 ...

  6. 最快的ASP无组件上传类(4M只需10秒)0.96版

    <% '---------------------------------------------------------------------- '转发时请保留此声明信息,这段声明不并会影响 ...

  7. ios12上滑关闭程序动画_iOS 12.3正式版终于来了:这类用户升级需谨慎!

    明美无限果粉关注不迷路! 文|明美无限 就在上周的时候,苹果公司突然不按常规出牌的发布了两个iOS 12.3测试版,那时明美无限也写了篇文章说苹果真的难得的实属罕见!相信很多果粉也关注了明美无限这么久 ...

  8. 为什么需要虚继承,虚继承的实现原理

    虚继承和虚函数是完全无相关的两个概念. 虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝.这将存在两个问题:其一,浪费存储空间:第二,存在二义性问题,通常可 ...

  9. 汉寿计算机培训初中升高中,升高中前,这几类学生只需注意这些,就有机会成为学霸...

    十二载的寒窗苦读,很多人认为:高中三年是至关重要的,高中三年只要努力,哪怕曾经在初中成绩不稳定,依然会考出不错的成绩,在高考的舞台上,至少能为自己留下浓墨淡彩的一笔. 殊不知,高考成绩是否足够抢眼,其 ...

最新文章

  1. 国防科技大学教授:殷建平——计算机科学理论的过去、现在与未来
  2. C语言数组学习 - 使用窗口版程序演示
  3. Python基础教程:在for循环搭配else的陷阱,你知道吗?
  4. 中国版LinkedIn呼之欲出
  5. Docker 部署应用、jar 工程 docker 方式部署
  6. matlab散点图与colorbar,MATLAB如何为图像做colorbar
  7. 聚类算法实现:DBSCAN、层次聚类、K-means、
  8. 如何从零设计结构清晰、操作友好的权限管理模块
  9. nodejs 中的 commonjs 模块化使用
  10. 计算机视觉 --基于opencv实现证件照换底色、翻转
  11. (一)NIST CSF-框架介绍
  12. JavaEE Day14 ServletHTTPRequest
  13. 阿里魔改的mysql叫啥_mysql 改变数据库名
  14. RTDB 实时数据库RTDB(Real-Time Data Base)基础
  15. 贴吧无耻霸屏技术! 几万阅读量的微信公众号都偷偷的使用它
  16. Verilog计数器0~9999
  17. 何为五笔输入的最高境界?
  18. 微波中继通信中的天馈线系统及检测工具——TFN天馈线测试仪(驻波比测试仪)100系列
  19. ORACLE学习(三)
  20. android基本功

热门文章

  1. 用seaborn 画出唯美的论文专用图片,自己定制python画图的数据集
  2. Boreas: 一种基于token 的精确并且大规模检测代码克隆的方法
  3. composer更新_深入学习Composer原理(四)
  4. NC:港大张彤团队-基于组学的耐药基因风险评估框架
  5. Microbiome:南土所梁玉婷组-稻田土壤产甲烷菌的共存模式
  6. 南农Nature Microbiology一作顾少华:我与铁载体的这5年
  7. EST:李芳柏团队揭示微生物介导的砷氧化耦合硝酸还原
  8. PNAS:水稻微生物组
  9. 斯坦福大学统计系教授带你玩转微生物组分析
  10. R语言在直方图条(柱形)上添加计数(count)或者百分比(percent)标签