继承和多态二:虚析构函数

虽然我们已经知道了什么是继承和多态,也明白了多态依赖于继承,但是在多态中存在哪些问题呢?

多态中可能存在的内存泄露问题

例如下面的程序中,在圆形Circle的类中定义一个圆心的坐标,并且坐标是在堆中申请的内存,则在mian函数中通过基类指针操作派生类对象的成员函数是没有问题的,可是在销毁对象内存的时候则只是执行了基类的析构函数,派生类的析构函数却没有执行,这会导致内存泄漏。换句话说如果delete后边跟基类的指针则只会执行基类的析构函数,如果delete后面跟的是派生类的指针,那么它即会执行派生类的析构函数,也会执行基类的析构函数

class Shape
{
public:virtual double calcArea(){...}//虚函数
    Shape();~Shape();....                              
private:....
};
Shape::Shape()
{
cout<<"class Shape was created"<<endl;
}
Shape::~Shape()
{
cout<<"class Shape was deleted"<<endl;
}
class Circle:public Shape
{
public:Circle(int x,int y,double r);~Circle();virtual double calcArea();//此处可不加virtual,但系统默认加上
    ....
private:double m_dR;Coordinate *m_pCenter;      //坐标类指针
    ....
};
Circle::Circle(int x,int y,double r)
{m_pCenter=new Coordinate(x,y);m_dR=r;cout<<"class Circle was created"<<endl;
}
Circle::~Circle()
{delete m_pCenter;m_pCenter=NULL;cout<<"class Circle was deleted"<<endl;
}
....
int main()
{Shape *shape1=new Circle(5,6,4.0);//基类对象,改成Circle *circle=new Circle(5,6,4.0)则为派生类对象shape1->calcArea();delete shape1;shape1=NULL;//派生类对象的内存未回收return 0;
}
打印结果可见,派生类的析构函数并没有被执行,而只是回收了开辟给基类对象的空间,那如何解决这个问题呢,固然可以通过delete派生类对象实现,除此之外,还可以引入虚析构函数,你看普通的虚函数都可以实现多态的动态联编,那对于析构函数呢?虚析构函数也会在最后对象销毁内存时动态链接到派生类对象。
可以这样解释它:如果基类当中定义了虚析构函数,那么基类的虚函数表当中就会有一个基类的虚析构函数的入口指针,指向的是基类的虚析构函数,派生类的虚函数表当中也会产生一个派生类的虚析构函数的入口指针,指向的是派生类的虚析构函数,这个时候使用基类的指针指向派生类的对象,delete掉基类指针,就会通过指向的基类的对象找到基类的虚函数表指针,从而找到虚函数表,在虚函数表中找到派生类的虚析构函数,从而使得派生类的析构函数得以执行,派生类的析构函数执行之后系统会自动执行父类的虚析构函数。即整个执行过程是:
  1. 基类的构造函数;
  2. 派生类的构造函数;
  3. ......
  4. 派生类的析构函数;
  5. 基类的析构函数。

virtual关键字可以修饰普通的成员函数,也可以修饰析构函数,但并不是没有限制

virtual在函数中的使用限制

    • 普通函数不能是虚函数,也就是说这个函数必须是某一个类的成员函数,不可以是一个全局函数,否则会导致编译错误。
    • 静态成员函数不能是虚函数 static成员函数是和类同生共处的,他不属于任何对象,使用virtual也将导致错误。
    • 内联函数不能是虚函数 如果修饰内联函数 如果内联函数被virtual修饰,计算机会忽略inline使它变成存粹的虚函数。(inline将会在后面的博客中介绍)
    • 构造函数不能是虚函数,否则会出现编译错误。

转载于:https://www.cnblogs.com/cvtoEyes/p/8492247.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/486753.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

李开复对话彭特兰:AI 不是单打独斗,应避免 AI 冷战!

来源&#xff1a;CSDN近日&#xff0c;创新工场董事长兼CEO李开复博士与阿莱克斯彭特兰教授&#xff08;Alex Pentland&#xff09;展开了一场”AI如何重塑人类社会”的精彩对话。《连线》杂志的资深撰稿人威尔奈特&#xff08;Will Knight&#xff09;主持了这场对话。阿莱克斯…

iphone最新款手机_iPhone 丢了99.9%能找回?这种做法不可信!!

目前&#xff0c;手机已经成为我们生活中必不可少的一部分&#xff0c;科技发展带来消费场景的变化&#xff0c;到处都能扫一扫&#xff0c;让手机显得更加重要&#xff0c;你可以不带钱包出门&#xff0c;但不能不带手机。丢钱包的概率变低&#xff0c;丢手机的概率变高了&…

sql获取日期相差天数oracle,找到oracle sql中两个日期之间的经过时间

当您减去两个DATE值(如enddate – startdate)时,您会得到带小数精度的天数差异,因此例如1.5表示1 1/2天或36小时.您可以使用大量数学将其转换为HH&#xff1a;MI&#xff1a;SS,但更简单的方法是使用NUMTODSINTERVAL函数将十进制值转换为INTERVAL DAY TO SECOND值&#xff1a;N…

唐杰:AI 未来靠迭代

来源 | 北京智源人工智能研究院未来十年人工智能将如何发展&#xff1f;清华大学教授、智源研究院副院长唐杰认为&#xff1a;认知智能将成为一个重要的且可能实现的方向。具体来说&#xff0c;便是 System 1 和 System 2 的循环往复&#xff0c;不断迭代&#xff0c;从而打造出…

影视感悟

《一条狗的使命》 首先要开心只要有可能&#xff0c;就竭尽全力去帮助别人舔你爱的人对过去的事不要一副苦瓜脸对未来也不要愁眉苦脸只要活在当下活在当下收住挑衅脾气烈火&#xff0c;不轻易做过激行为&#xff0c;不轻易先动手打人 转载于:https://www.cnblogs.com/linkenpar…

php中用户验证的方式,在php中进行用户身份验证的最佳方式是什么?

使用Sessions.将会话ID存储在cookie中,并将用户的状态存储在服务器端(loggedIn,userId,IP).澄清您需要存储在会话数组中&#xff1a;> loggedIn&#xff1a;一个关于用户是否登录的布尔变量.您可以为多个会话重复使用相同的Cookie,因此您可以在下次访问您的网站时记住用户的…

linux服务器配置与管理_服务器维护实施步骤

为了有效地维护服务器&#xff0c;服务器管理员必须执行主动的硬件和软件检查。而服务器的维护清单必须包括除尘、日志查看、软件补丁程序测试等。即使具有服务器的性能和冗余功能&#xff0c;增加的工作负载整合和可靠性期望也会对服务器硬件造成损害。服务器维护清单应涵盖物…

常用数据库的分页实现

MySQL&#xff1a; 可以得出符合我们自己需求的分页sql格式是&#xff1a;select * from table limit (start-1)*limit,limit; 其中start是页码&#xff0c;limit是每页显示的条数。 SqlServer&#xff1a; Oracle&#xff1a; 转载于:https://www.cnblogs.com/gzu-link-pyu/p/…

量子信息技术研究现状与未来

来源&#xff1a;专知量子信息技术是量子力学与信息科学融合的新兴交叉学科, 它的诞生标志着人类社会将从经 典技术迈进到量子技术的新时代, 本文将阐述量子信息技术的研究现状与未来. 文中描绘了量子技术 发展远景, 即筑建各种类型的量子网络, 包括量子云计算网络、分布式量子…

检测oracle的语句,oracle功能检测sql语句

1. 监控事例的等候select event,sum(decode(wait_Time,0,0,1)) "Prev",sum(decode(wait_Time,0,1,0)) "Curr",count(*) "Tot"from v$session_Waitgroup by event order by 4;2. 回滚段的争用情况select name, waits, gets, waits/gets "Rat…

idea springmvc项目搭建_ssm框架整合搭建流程 - 小白小承

刚学完Mybatis&#xff0c;Spring&#xff0c;SpringMVC尝试进行一个整合开发&#xff0c;记录一下搭建流程1.环境与开发工具IDEAMySQL 8.0.16Tomcat 9.0.21Maven 3.6.12.项目准备1.创建一个maven工程2.依赖注入<dependencies><dependency><groupId>junit<…

21世纪科技生态面临第三次全球标准

来源&#xff1a;中国社会科学报 前言&#xff1a;本文2020年9月29日发表与“中国社会科学报”&#xff0c;原文标题"科技生态面临新全球标准”&#xff08;略有修改&#xff09;。2007年以来&#xff0c;我们对21世纪前沿科技生态发展的规律进行研究。提出互联网从网状…

adb push ,adb pull和adb install的区别

1、用命令行把手机上的文件拷贝到电脑上 1adb pull sdcard/1222073679.png拷贝文件夹命令&#xff0c;如把log文件夹拷贝到电脑当前目录 1adb pull sdcard/log/拷贝文件夹到当前文件夹下的某文件夹里面&#xff0c;如拷贝360文件夹到当前文件夹的360里面 1adb pull sdcard/360/…

php+jquery实现图片上传预览_和拖动位置值,PHP教程:thinkphp jquery实现图片上传和预览效果...

《PHP教程&#xff1a;thinkphp jquery实现图片上传和预览效果》要点&#xff1a;本文介绍了PHP教程&#xff1a;thinkphp jquery实现图片上传和预览效果&#xff0c;希望对您有用。如果有疑问&#xff0c;可以联系我们。PHP学习PHP学习那个file按钮样式先忽略PHP学习点击选择图…

屏幕中间显示已停用缩放_有关标签打印软件缩放工具的介绍

在标签打印软件中设计标签时&#xff0c;为了方便编辑&#xff0c;有时会根据自己的需求放大缩小标签来精确位置大小等&#xff0c;做更细致的调整&#xff0c;这时就会用到缩放工具。下面&#xff0c;主要就是给大家介绍标签打印软件缩放工具的用处&#xff1a;在标签打印软件…

集合(2)

Linkedlist特有的方法 增加头Link.addFirst(“tou”); 增加尾Link.addLast(“tou”); 获取头Link.getFirst(); 获取尾Link.getLast(); 获取并删除头Link.removeFirst(); 获取并删除尾Link.removeLast(); 在获取元素时&#xff0c;链表为空就会报notsuchelementException。 在1.…

机器学习揭示了人类大脑的新见解

来源&#xff1a;科学杂志由新加坡国立大学(NUS)科学家领导的跨学科研究团队已成功地利用机器学习来发现对人脑细胞结构的新见解。该团队展示了一种使用从功能磁共振成像(fMRI)收集的数据自动估算大脑参数的方法&#xff0c;使神经科学家无需使用手术手段即可探测大脑&#xff…

dram和nand哪个难生产_仅300名员工,年产7台,订单排到5年后,比光刻机还难买...

如今半导体行业发展成为如今一大热议话题&#xff0c;如今不管在哪个行业几乎都要用到芯片&#xff0c;在以前可能手机行业对于芯片的需求量更高一些&#xff0c;然而近些年来不同领域的厂商都争相开始发展智能机&#xff0c;而这其中就离不开芯片技术&#xff0c;华为的麒麟芯…

bitset与取数凑数类问题

bitset是C中的一个东西&#xff0c;定义在头文件#include<bitset>里 所以可以使用#include<bitset>解决取数类的问题https://www.nowcoder.com/acm/contest/1/D 转载于:https://www.cnblogs.com/MekakuCityActor/p/8513734.html

oracle.01081 cannot,ORA-01081: cannot start already-running ORACLE - shut it down first

Applies to:Oracle Server - Enterprise Edition - Version: 8.1.7.4 to 11.2.0.2.0 - Release: 8.1.7 to 11.2Generic UNIX当检查oracle实例后台进程不存在这时启动启动数据库报错:ORA-01081: "cannot start already-running ORACLE - shut it down first"造成此种原…