【拒绝主观!】C++继承中父类的构造函数和析构函数调用情况

2023-11-03

C++继承中父类的构造函数和析构函数调用情况

父类构造函数调用规则

  • 子类会默认调用父类的无参构造函数,且发生在子类所有代码执行之前。

原因:父类里面的一些成员可能被设置为private,导致该成员变量只能由父类自己初始化。

  • 如果父类不存在无参构造函数,那子类必须显式调用父类的构造函数。
  • 如果父类没有构造函数,则子类不调用父类构造函数。

对于代码:

#include<iostream>
using namespace std;

class Person {
private:
	int age;
};
class Student : Person {
public:
	Student() {
		cout << "Student::Student()" << endl;
	}
};
int main() {
	Student student;
}

Student类默认构造方法汇编代码(Visual Studio 2019平台)如下:

class Student : Person {
public:
	Student() {
009C1F00  push        ebp  
009C1F01  mov         ebp,esp  
009C1F03  sub         esp,0CCh  
009C1F09  push        ebx  
009C1F0A  push        esi  
009C1F0B  push        edi  
009C1F0C  push        ecx  
009C1F0D  lea         edi,[ebp-0CCh]  
009C1F13  mov         ecx,33h  
009C1F18  mov         eax,0CCCCCCCCh  
009C1F1D  rep stos    dword ptr es:[edi]  
009C1F1F  pop         ecx  
009C1F20  mov         dword ptr [this],ecx  
009C1F23  mov         ecx,offset _C3F9A43E_main@cpp (09CF029h)  
009C1F28  call        @__CheckForDebuggerJustMyCode@4 (09C1384h)  
		cout << "Student::Student()" << endl;

其中没有对于父类Person构造方法的调用(类似call的语句),所以父类不写构造函数时,子类不会调用父类构造函数,也即并不是编译器自动生成一个构造函数给子类调用。

父类析构函数调用规则

  • 当父类和子类的析构函数都显式声明时,子类的析构函数会默认调用父类的析构函数,且会在子类的析构函数最后调用。

原因:父类中可能有一些成员变量被设置为private,那么子类继承下来的这些成员变量必须由父类自己来释放。

  • 当父类的析构函数不显式声明时,子类不会调用父类的构造方法。

对于代码:

#include<iostream>

using namespace std;

class Person {
private:
	int age;
};

class Student : Person {
public:
	Student() {
		cout << "Student::Student()" << endl;
	}
	~Student()
	{
		cout << "Student::~Student()" << endl;
	}
};

int main() {
    // student在栈空间定义,用大括号限定其生命周期,便于看到析构函数的调用。
	{
		Student student;
	}
}

Student类析构函数汇编代码(Visual Studio 2019平台)如下:

	~Student()
	{
002221C0  push        ebp  
002221C1  mov         ebp,esp  
002221C3  push        0FFFFFFFFh  
002221C5  push        2274A0h  
002221CA  mov         eax,dword ptr fs:[00000000h]  
002221D0  push        eax  
002221D1  sub         esp,0CCh  
002221D7  push        ebx  
002221D8  push        esi  
002221D9  push        edi  
002221DA  push        ecx  
002221DB  lea         edi,[ebp-0D8h]  
002221E1  mov         ecx,33h  
002221E6  mov         eax,0CCCCCCCCh  
002221EB  rep stos    dword ptr es:[edi]  
002221ED  pop         ecx  
002221EE  mov         eax,dword ptr [__security_cookie (022C004h)]  
002221F3  xor         eax,ebp  
002221F5  push        eax  
002221F6  lea         eax,[ebp-0Ch]  
002221F9  mov         dword ptr fs:[00000000h],eax  
002221FF  mov         dword ptr [this],ecx  
00222202  mov         ecx,offset _C3F9A43E_main@cpp (022F029h)  
00222207  call        @__CheckForDebuggerJustMyCode@4 (0221384h)  
		cout << "Student::~Student()" << endl;
0022220C  mov         esi,esp  
0022220E  push        offset std::endl<char,std::char_traits<char> > (022103Ch)  
00222213  push        offset string "Student::~Student()" (0229BE4h)  
00222218  mov         eax,dword ptr [__imp_std::cout (022D0D4h)]  
0022221D  push        eax  
0022221E  call        std::operator<<<std::char_traits<char> > (02211AEh)  
00222223  add         esp,8  
00222226  mov         ecx,eax  
00222228  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (022D0A0h)]  
0022222E  cmp         esi,esp  
00222230  call        __RTC_CheckEsp (0221294h)  
	}

可以看出,在最后并没有调用父类的析构函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【拒绝主观!】C++继承中父类的构造函数和析构函数调用情况 的相关文章

随机推荐

  • OpenCV各个模块介绍

    对于初学opencv的我来说 最头疼和无法下手的就是 都有什么库 那些库都是干什么的 怎么用 我想很多人应该和我一样 我觉得最重要的就是需要先知道opencv有哪些库 都是干什么的 在我们安装opencv的地址下 可以看到opencv2中包
  • 使用rpm包搭建Glusterfs集群

    使用rpm搭建Glusterfs集群步骤 一 环境准备 1 准备搭建glusterfs所需的rpm包 centos release gluster6 1 0 1 el7 centos noarch rpm centos release st
  • mysql中空值和null值的区别及处理方法总结

    一直对空值和null值的概念理解不清晰 所以结合资料以及自己的理解对他们的区别和处理方式进行总结 首先就是在概念上的不同 1 空值不占空间 2 null值占空间 打个比喻就是空值表示一个杯子是真空状态 什么都没有 而null值是杯子中有空气
  • Java 8 中的抽象类和接口到底有啥区别?

    在我们面试时也会经常遇到面试官问抽象类和接口的区别是什么 大部人肯定会说 接口中的所有方法都是抽象的 抽象类中的方法除了抽象方法还可以写实现方法 如果你还这样回答那你就 OUT 啦 要跟上形式 这个问题我在面试一个 39 岁的程序员时 他居
  • Redis配置文件解读

    转载自 http www cnblogs com daizhj articles 1956681 html 对部分配置选项做了一些说明 把配置项目从上到下看了一遍 有了个大致的了解 暂时还用不到一些高级的配置选项 先放在这 用到的时候再回来
  • Teradata SQL 线性回归函数

    基于budget amounts排队得到前三个部门 显示部门号和预算 SELECT department number salary amount RANK salary amount AS Rank FROM dapartment QUA
  • Typescript(九)配置文件 tsconfig.json

    TypeScript 使用 tsconfig json 文件作为其配置文件 当一个目录中存在 tsconfig json 文件 则认为该目录为 TypeScript 项目的根目录 通常 tsconfig json 文件主要包含两部分内容 指
  • unity

    一 理解我们要做的事 原本图片放入文件夹后是Default 默认 模式 但是需要大量处理图片的时候 我们希望它拖进去就是sprite模式 我们想修改unity原本的功能 二 unity是允许我们去修改它本身的一些功能的 你可以定制属于你的u
  • JVM系列(十) 垃圾收集器之 Parallel Scavenge/Old

    上篇文章我们讲解了单线程垃圾收集器 Serial SerialOld 与之相对应的多线程垃圾收集器就是 Parallel Scavenge Old 本文我们讲解下多线程垃圾收集器 Parallel Scavenge Old 垃圾收集器 新生
  • 2018年TI杯电子设计竞赛感悟

    2018年7月27日 电赛结束已经有三四天的时间了 今年的感悟和去年的相比很是不同 去年大一 刚刚入门单片机 搞点东西也都是瞎搞 没有一个像模像样的作品 即使是有也都是一些次品 半成品 得知学校选拔学生参加全国大学生电子设计竞赛 单数年为国
  • linux添加sshkey,linux 配置 ssh密钥登陆

    配置这个其实很简单 一点也不复杂 首先需要在服务器安装openssh 如果你不安装你是找不到配置密钥登陆的配置文件的 yum install y openssh 安装好后就需要去配置密钥登陆了 vi etc ssh sshd config
  • kali持久化U盘镜像安装教程

    https zhuanlan zhihu com p 436210497 utm id 0
  • opencv 轻松入门 面向python pdf_面向Python 的OpenCV轻松入门——第三章(3)

    3 3 按位逻辑运算 逻辑运算是一种非常重要的运算方式 图像处理过程中经常要按照位进行逻辑运算 本节 介绍 Opencv中的按位逻辑运算 简称位运算 在 Opencv内 常见的位运算函数如表3 1所示 表3 1 常见的位运算函数 函数名 基
  • linux的依赖关系

    依赖关系最简单的一个理解就是 Windows 上你玩游戏结果提示 directx 版本过低无法运行 以及常见的运行某个程序之后提示 mfc71 dll 未找到 还有就是用个软件结果安装说明上让你先去安装 net Linux 的依赖关系因为他
  • iOS开发入门教程

    当涉及到详细的教程和排版要求时 纯文本形式的回答无法满足您的需求 以下是一个简单的iOS开发入门教程大纲 您可以按照该大纲进行深入学习和实践 iOS开发入门教程大纲 1 开发环境搭建 下载和安装Xcode 配置iOS模拟器 2 Swift语
  • Echarts

    目录 1 1 什么是ECharts 1 2 ECharts基本使用 1 3 ECharts标题组件 1 4 ECharts工具箱组件 1 5 ECharts弹窗组件 1 6 ECharts饼状图 1 7 ECharts航线图 更详细的教程请
  • spice协议详解(二):spice支持功能和优势

    SPICE Simple Protocol for Independent Computing Environments 是目前最有潜力的开源虚拟桌面协议 最初是由Qumranet开发 后来被RedHat收购并开源 经过几年的社区开发 sp
  • 爆肝整理,Python自动化测试-Pytest参数化实战封装,一篇打通...

    目录 导读 前言 一 Python编程入门到精通 二 接口自动化项目实战 三 Web自动化项目实战 四 App自动化项目实战 五 一线大厂简历 六 测试开发DevOps体系 七 常用自动化测试工具 八 JMeter性能测试 九 总结 尾部小
  • [大话IT]圈套玄机—《圈子圈套》中的案例分析

    2006 02 22 00 20 14 Filter pattern 楼主 supernal pig 地址 http www12 tianya cn new Publicforum Content asp idWriter 2974942
  • 【拒绝主观!】C++继承中父类的构造函数和析构函数调用情况

    C 继承中父类的构造函数和析构函数调用情况 父类构造函数调用规则 子类会默认调用父类的无参构造函数 且发生在子类所有代码执行之前 原因 父类里面的一些成员可能被设置为private 导致该成员变量只能由父类自己初始化 如果父类不存在无参构造