C++继承机制下析构和构造函数的执行分析

news2024/11/20 4:34:45

析构函数在下边3种情况时被调用:

  1. 对象生命周期结束,被销毁时;
  2. delete指向对象的指针时,或delete指向对象的基类类型指针,而其基类虚构函数是虚函数时;
  3. 对象i是对象o的成员,o的析构函数被调用时,对象i的析构函数也被调用。

派生体系中:

析构函数的调用规则:

  1. 对于派生类对象,若不使用基类对象指向他,直接delete该则调用它的析构函数,再调用它成员、基类的析构函数,依此类推。
  2. 自动对象(局部的)在离开作用域的时候自动调用析构函数。(确切的说是编译器在离开对象作用域的时候添加析构函数的代码)
  3. new出来的对象要有delete时才调用析构函数。
  4. 基类指针可以指向派生类,这时候必须吧基类的析构函数声明为虚函数,否则无法释放子类资源,会导致内存泄漏。

构造与析构顺序相反:

  1. 当派生类中不含对象成员时 :
    在创建派生类对象时,构造函数的执行顺序是:基类的构造函数→派生类的构造函数;
    析构函数相反。
  2. 当派生类中含有对象成员时 :
    在定义派生类对象时,构造函数的执行顺序:基类的构造函数→对象成员的构造函数→派生类的构造函数;
    析构函数相反。

看些例子:

#include <iostream>
using namespace std;
class A { public: ~A(); };//情况1
//class A { public: virtual ~A(); };//情况2
 A::~A() { printf("delete A "); }
class B :public A { public: ~B(); };
 B::~B() { printf("delete B "); }
int main() {
    //int a;
    //cin >> a;
    A *pa = new B();
    delete pa;
    //cout << "Hello World!" << endl;
}

看A加不加virtual时候的输出

结果:

情况1:
在这里插入图片描述

情况2:

在这里插入图片描述

解析:

情况1中,父类A析构函数不是virtual,故无法使用虚函数机制调用子类B的析构函数。

情况2中,父类A析构函数是virtual,使用虚函数机制调用子类B的析构函数,由于B类中含有A对象,根据上述析构函数调用第三条规则,故会在之后调用A的析构函数。

-----------------------分界线-------------------------------------------------------------------------------

需要指出的是,C++将内存处理交给用户,所以在上述情况中,虽然我们内存释放的不正确,例如B中有堆上的数据,这会导致这些堆上的数据不能释放,但是,IDE仍然认为这里我们new出的这个B类型对象被释放了,所以,这里就产生了常见的内存泄漏:

#include <iostream>
using namespace std;
class A { 
    public: ~A(); //情况1
    //public: virtual ~A();//情况2
    int x = 1;
    virtual void printX() {

    }
};
A::~A() { printf("delete A "); }
class B :public A {
public:
    int *leakMemory  = new int[10];//泄漏
    virtual void printX() {
        //cout << x << endl;
        cout << 2 << endl;
    }
    ~B(); 
};
B::~B() { printf("delete B "); }
int main() {
    B* pb= new B();
    A* pa= pb;
    A* paa = pa;
    paa->printX();
    delete pa;
    pb->printX();
    //cout << "Hello World!" << endl;
}

这里leakmemory的释放由~ B来做,但是在没有将~ A设置为virtual的情况下,虽然~B没有执行,leakmemory没有被释放,但是IDE仍然认为这个B对象已经被释放,我们无法再使用这个对象,这就造成了内存泄漏。
在这里插入图片描述

稍微复杂点的的例子,可以判断结果检验自己是否理解:

#include <iostream>
using namespace std;
class A {
public:
    A() { cout << "A" << endl; }
    virtual void AB_test() { cout << "A_test" << endl; }
    //~A() { cout << "~A" << endl; AB_test(); }//case 3
    virtual ~A() { cout << "~A" << endl; AB_test(); }//case 4
};

class B :public A {
public:
    B() { cout << "B" << endl; }
    ~B() { cout << "~B" << endl; AB_test(); }
    virtual void AB_test() { cout << "B_test" << endl; }
};
int main()
{
    A* b = new B;
    delete b;
    return 0;
}

结果:

case3:

在这里插入图片描述

case4:

在这里插入图片描述

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

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

相关文章

SRM 供应商管理系统都有哪些模块?

3k字干货&#xff01; SRM必备6大模块&#xff1a;供应商管理、采购需求管理、采购寻源、采购履约、交付结算。下面针对环节中的核心场景进行讲解。 1、供应商全生命周期管理 过去&#xff0c;企业业务简单&#xff0c;对接供应商数量少&#xff0c;需求供给匹配、价格合适就…

如何使用KoodousFinder搜索和分析Android应用程序中的安全威胁

关于KoodousFinder KoodousFinder是一款功能强大的Android应用程序安全工具,在该工具的帮助下,广大研究人员可以轻松对目标Android应用程序执行安全研究和分析任务,并寻找出目标应用程序中潜在的安全威胁和安全漏洞。 账号和API密钥 在使用该工具之前,我们首选需要访问该…

适合初创企业租赁的办公模式-共享办公室

随着共享经济的兴起&#xff0c;共享办公室已经成为越来越多人的选择。共享办公室提供了一个灵活、高效、舒适的工作环境&#xff0c;能够帮助个人和团队提高工作效率和创造力。下面我将从三个角度来介绍共享办公室。 共享办公室的优势 首先&#xff0c;共享办公室具有成本效益…

合肥先进光源束测步进电机及驱动器的选择

大规模电机控制的方案选择-电机和驱动器篇 在上面文档的系统里选择的是免电池带绝对值编码器的步进伺服电机方案&#xff0c;现在有些场合只是普通的步进电机就好了&#xff0c;同样从电机控制的龙头企业鸣志的产品中选择&#xff0c;依然选择现成熟的ethercat总线技术的驱动器…

深度学习模型在图像识别中的应用:CIFAR-10数据集实践与准确率分析

文章目录 前言导入所需的库忽略证书验证下载并加载 CIFAR-10 数据集数据预处理构建深度学习模型编译模型模型训练模型评估进行图片识别测试图片运行效果完整代码完结 前言 深度学习模型在图像识别领域的应用越来越广泛。通过对图像数据进行学习和训练&#xff0c;这些模型可以自…

ChatGPT独家汇总:发现最优秀的人工智能对话体验

欢迎来到我们的 ChatGPT 镜像网站汇总博客&#xff01;在这个令人激动的人工智能时代&#xff0c;ChatGPT 作为一款顶尖的语言模型&#xff0c;已经引起了全球范围内的热议。但是&#xff0c;您是否曾经为了找到最佳的 ChatGPT 使用体验而苦苦搜寻&#xff1f;别担心&#xff0…

(15)第一人称视角视频

文章目录 前言 15.1 推荐的零件 15.2 连接图示 15.3 通过任务计划器最小化OSD设置 15.4 集成式OSD 15.5 用户视频/博客 15.6 与FPV飞行特别相关的安全警告 15.7 政府/地方法规 前言 第一人称视角在飞行时为你提供了真正的飞行员视角&#xff0c;它将视频摄像机和发射器…

梯度下降求函数极小值

梯度下降求函数极小值 Himmelblau 函数表达式 ∫ ( x , y ) ( x 2 y − 11 ) 2 ( x y 2 − 7 ) 2 \int(x,y)(x^{2}y-11)^{2} (xy^{2}-7)^{2} ∫(x,y)(x2y−11)2(xy2−7)2 Himmelblau.py 绘制 import numpy as np import matplotlib.pyplot as plt# from mpl_toolkits.mp…

Redis中的缓存雪崩、击穿、穿透的原因以及解决办法

缓存雪崩、击穿、穿透一旦发生&#xff0c;会导致大量的请求积压到数据库层。如果请求的并发量很大&#xff0c;就会导致数据库宕机或是故障&#xff0c;这就是很严重的生产事故了。 俗话说&#xff0c;知己知彼&#xff0c;百战不殆。了解了问题的成因&#xff0c;我们就能够…

PentestGPT:一款由ChatGPT驱动的强大渗透测试工具

关于PentestGPT PentestGPT是一款由ChatGPT驱动的强大渗透测试工具,该工具旨在实现渗透测试任务执行过程的自动化。该工具基于ChatGPT实现其功能,允许广大研究人员以交互式的方式使用,并指导渗透测试人员进行渗透测试任务的总体进度调控并执行指定操作。 除此之外,Pentes…

[学习笔记]python的web开发全家桶2(ing)

初识网站 默认编写的静态的效果动态&#xff1a;需要用到Web框架的功能。 对于目前的我们来看&#xff0c;什么可以做数据存储&#xff1a;txt文件excel文件专业的软件&#xff1a;数据库管理系统 MySQL/Oracle/SQLServer/DB2/Access... 7 MysQL 7.1 安装MySQL MySQL&…

#10042. 「一本通 2.1 练习 8」收集雪花

题目描述 不同的雪花往往有不同的形状。在北方的同学想将雪花收集起来&#xff0c;作为礼物送给在南方的同学们。一共有 n 个时刻&#xff0c;给出每个时刻下落雪花的形状&#xff0c;用不同的整数表示不同的形状。在收集的过程中&#xff0c;同学们不希望有重复的雪花。你可以…

Tomcat【redis-session共享】

目录 1、创建虚拟主机&#xff08;01-02&#xff09;相同【192.168.200.121、192.168.200.122】 2、LB配置文件【192.168.200.120】 3、tomcat节点配置TomcatClusterRedisSessionManager方式实现redis共享&#xff08;01-02&#xff09;相同 4、安装redis、配置【192.168.20…

智慧餐饮未来:点赋科技智能饮品机器人带来的变革

随着科技的不断发展&#xff0c;智慧餐饮作为餐饮行业的新兴概念已经不再只是简单的餐厅智能化&#xff0c;而是包括了数字化、智能化和现代化等多个方面。点赋科技智能饮品机器人是智慧餐饮中最具代表性的之一&#xff0c;它的发展将引领智慧餐饮行业的未来方向。 首先&#x…

TIA博途Wincc中制作电机风扇或水泵旋转动画的具体方法示例

TIA博途Wincc中制作电机风扇或水泵旋转动画的具体方法示例 如下图所示,打开TIA博途软件,新建一个项目,添加一个1215 PLC,双击进入设备组态,设置属性—常规—系统和时钟存储器,勾选“启用系统存储器字节”、“启用时钟存储器字节”, 如下图所示,添加一个全局DB块,这里…

【Java】02--变量与数据类型Scanner

文章目录 1.什么是常量&#xff0c;什么是变量2.数据类型2.1什么是数据类型转换 3.为什么要使用Scanner 1.什么是常量&#xff0c;什么是变量 你只需要记住两点&#xff1a; 常量&#xff1a;就是一种不会根据环境而改变的数据&#xff0c;例如&#xff1a;圆周率。 变量&…

网络io模型、同步异步及Sanic和uvloop

网络io模型及基础概念 概念说明 用户空间与内核空间 操作系统的核心是内核&#xff0c;独立于普通的应用程序&#xff0c;可以访问受保护的内存空间&#xff0c;也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核&#xff08;kernel&#xff09;&#xff0…

银河麒麟系统安装mysql数据库[mysql-5.7.28-linux-glibc2.12-x86_64]

银河麒麟系统安装mysql数据库 1.1 准备材料 mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz MySQL5.7下载地址 https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz 1.1 安装前准备工作 1、检查是否已经安装MySQL [rootlocalhost ~]# rpm …

使用虚拟引擎创建海盗船长角色分解

介绍 你好&#xff01;我叫 Stapan&#xff0c;我是电影和电影的角色艺术家&#xff0c;我有在动画工作室担任自由艺术家和角色艺术家的经验&#xff0c;现在我正在与 Artem Gansior 领导的 ODEE 团队一起制作一部短片。 参考 对于这个项目&#xff0c;最初的角色概念是由超…

MAYA曲线粒子

不从粒子中心发射 nParticleShape1.massrand(0.5,0.7);