66 C++对象模型探索。C++编译器在什么时候给我们创建默认的构造函数?

news2024/12/28 11:18:38

一 前提,关于C++编译器给我们生成 默认构造函数 的错误认知

传统知识认为:如果在一个类中,我们没有定义任何的构造函数,那么编译器会为我们隐式自动定义一个默认的构造函数,我们称这种构造函数为 "合成的默认构造函数"

实际上这个结论是错误的,正确的说法是:如果在一个类中,我们没有定义任何的构造函数,那么编译器 会在必要的时候 为我们隐式自动定义一个默认的构造函数,我们称这种构造函数为 "合成的默认构造函数"。

也就是说:在类没有构造函数的情况下,有可能 C++编辑器 会生成 "合成的默认构造函数",有可能不会合成

二 那么什么是必要的时候呢?以及怎么验证这个问题呢?

2.1 如何验证这个问题?使用工具分析对应的.obj或者.o文件

每个.cpp文件都会编译生成一个.obj文件,或者一个.o文件

windows : vs2017生成.obj文件

linux : linux生成.o文件

我们可以通过工具分析这个.obj文件,检查是否有构造函数的生成

工具在哪里?

windows:  vs2017中的 "VS 2017的开发人员命令提示符 "

linux:

文件在哪里 ?即 .obj 或者 .o文件的位置?

vs2017 : 在debug目录下

如何使用?使用dumpbin命令分析 .obj文件,将分析出来的内容写到一个txt文件中,方便分析

打开 "VS 2017的开发人员命令提示符 "
cd 到.obj文件目录下
dempbin/all teacher100.obj > my.txt

D:\AllInformation\cpp\001for\001for\ConsoleApplication1\x64\Debug>dumpbin /all ConsoleApplication1.obj > my.txt

然后在 my.txt中 去查找 关键字 Teacher11::Teacher11,,就会发现在obj中确实没有构造函数的

好了现在我们工具有了,方法有了,写一个case验证一下。

2.2 结论1:如果该类Teacher11 没有任何构造函数,但是包含了一个其他类的成员变量Teacher10,而且包含的这个对象类型是有 明确的构造函数的。这时候,编译器会给我们自动生成默认的构造函数,编译器自动合成这个默认的构造函数的目的是:在这个自动生成的默认的构造函数中,会调用Teacher10的构造函数,以保证Teacher10可以被初始化。如果包含了多了其他类成员,例如有Teacher10,Teacher9,Teacher8,那么这个调用顺序为 在Teacher11中定义的顺序。

class Teacher10 {
public:
	Teacher10() {
		cout << "teacher10 的构造函数被调用"<<endl;
	}
};

class Teacher11 {

	Teacher10 tea10;
};

void main() {
	Teacher10 tea10;
	Teacher11 tea11;
	cout << "start " << endl;
}

2.3 结论2:如果该类Teacher14 没有任何构造函数,但是它的爸爸Teacher12明确的构造函数的。这时候,编译器会给我们自动生成默认的构造函数,编译器自动合成这个默认的构造函数的目的是:在这个自动生成的默认的构造函数中,会调用它的父类Teacher12的构造函数,以保证Teacher12可以被初始化。

如果多继承,即Teacher14,继承了 Teacher12,也继承了Teacher13,也是那个爸爸有明确的构造函数,生成的默认构造函数会调用 爸爸的构造函数,不会给没有明确构造函数的爸爸生成默认构造函数。也不会调用没有明确构造函数的爸爸

class Teacher12 {
public:
	Teacher12() {

	}
};
class Teacher13 {

};

class Teacher14 :public Teacher12{//会生成14的默认构造函数,不会生成13的
//class Teacher14 :public Teacher12, public Teacher13 {//会生成14的默认构造函数,不会生成Teacher13的构造函数
public:

};

void main() {
	Teacher14 tea14;
	Teacher12 tea12;
	Teacher13 tea13;
}

2.4 结论3:如果一个类中含有虚函数,但是没有任何构造函数。编译器会给我们生成一个默认的构造函数。编译器会给我们生成一个基于该类的虚函数表 vftable.

那么这个构造函数又干了些什么呢?将虚函数表的指针和类对象关联起来。

如下的解释,如果看不懂,没关系,后续在虚函数的整理学习中---详细解释。这里只要知道上面的结论就行。

//因为虚函数的存在,编译器会给我们生成一个基于该类的虚函数表 vftable,这个虚函数表有很多项,每一项都记录着每一个虚函数的地址。

//在这个构造函数中,会把类的虚函数表地址赋给类对象的 虚函数表指针(赋值语句 )。

//我们可以把 虚函数指针,看成是我们表面上看不见的一个类的成员变量。因此

//虚函数是跟着类走的。

//为什么这么麻烦,因为虚函数的调用存在一个多态问题

如果我们有虚函数,也有显示的构造函数呢?编辑器会给我们这个显示的构造函数中,添加代码,添加的代码也不难想象;会给我们生成虚函数表,将虚函数表的地址 赋给 对象的虚函数表指针。

2.5 结论4:如果一个类带有虚基类,编译器也会为他合成一个默认的构造函数。可以不关注这个,写在这里,只是为了知识的完整性,实际工作中,谁要搞这个,会被code review致死。

虚基类:通过两个直接基类继承同一个基类。所以一般有三层,有爷爷Grand,有两个爹A,A2,有孙子C

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

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

相关文章

ElasticSearch 7.x现网运行问题汇集3

问题描述 某现网ElasticSearch 故障&#xff0c;很长时间unassgined_shards的数量都不减少。 原因分析与解决方案&#xff1a; 先了解整体状态&#xff0c;使用Postman请求&#xff0c;如下几个请求命令&#xff1a; GET /_cat/indicesGET /_cat/shardsGET /_cluster/health…

Minio搭建和使用

目前可用于文件存储的网络服务选择也有不少&#xff0c;比如阿里云OSS、七牛云、腾讯云等等&#xff0c;可是收费都有点小贵。为了节约成本&#xff0c;很多公司使用MinIO做为文件服务器。 MinIO是一个开源的分布式对象存储服务器&#xff0c;支持S3协议并且可以在多节点上实现…

Conmi的正确答案——使用eclipse进行ESP32C3的debug

eclipse IDE 版本&#xff1a;2023-12 1、安装debug环境 参考大神的教程&#xff1a;【图文】手把手教你使用 Eclipse IDE 开发 ESP32 &#xff08;这里是为了我下次回来速通才写的部分&#xff09; 1.1、安装插件&#xff08;plug-in&#xff0c;新的软件已经写成software了…

Docker安装启动、常用命令、应用部署、迁移备份、Dockerfile、Docker私有仓库

目录 1.Docker安装与启动 1.1 安装Docker 1.2 设置ustc的镜像 1.3 Docker的启动与停止 2.常用命令 2.1 镜像相关命令 2.1.1 查看镜像 2.1.2 搜索镜像 2.1.3 拉取镜像 2.1.4 删除镜像 2.2 容器相关命令 2.2.1 查看容器 2.2.2 创建与启动容器 2.2.3 停止与启动容器 2.…

仿真机器人-深度学习CV和激光雷达感知(项目2)day5【作业1与答案1】

文章目录 前言作业1答案1 前言 &#x1f4ab;你好&#xff0c;我是辰chen&#xff0c;本文旨在准备考研复试或就业 &#x1f4ab;本文内容是我为复试准备的第二个项目 &#x1f4ab;欢迎大家的关注&#xff0c;我的博客主要关注于考研408以及AIoT的内容 &#x1f31f; 预置知识…

Java - 单元测试及Junit的使用讲解及练习

目录 &#x1f436;2.1 什么是单元测试 &#x1f436;2.2 测试分类&#xff1a; 1. &#x1f959;黑盒测试 2. &#x1f959;白盒测试 &#x1f436;2.3 Junit介绍 &#x1f436;2.4 Junit的基本使用步骤:(默认使用maven创建项目) 1. &#x1f959;pom.xml中引入依赖: 2…

考试查分场景重保背后,我们如何进行可用性测试

作者&#xff1a;暮角 随着通过互联网音视频与知识建立连接的新学习方式在全国范围内迅速普及&#xff0c;在线教育/认证考试的用户规模呈井喷式增长。但教育容不得半点马虎与妥协&#xff0c;伴随用户规模不断增长&#xff0c;保证系统稳定性、有效避免千万考生考试时遭遇故障…

14 STM32 - IIC (时序图+软件源码)

14.1 IIC简介 IIC&#xff08;Inter-Integrated Circuit&#xff09;&#xff0c;中文集成电路总线&#xff0c;是一种串行通信总线&#xff0c;使用多主从架构。I2C串行总线一般有两根信号线&#xff0c;一根是双向的数据线SDA&#xff0c;另一根是时钟线SCL。所有接到I2C总线…

目标检测 - 绘制bounding box

工具类 from PIL.Image import Image, fromarray import PIL.ImageDraw as ImageDraw import PIL.ImageFont as ImageFont from PIL import ImageColor import numpy as npSTANDARD_COLORS [AliceBlue, Chartreuse, Aqua, Aquamarine, Azure, Beige, Bisque,BlanchedAlmond, …

C++提高编程---模板---类模板

目录 一、类模板 1.模板 2.类模板的作用 3.语法 4.声明 二、类模板和函数模板的区别 三、类模板中成员函数的创建时机 四、类模板对象做函数参数 五、类模板与继承 六、类模板成员函数类外实现 七、类模板分文件编写 八、类模板与友元 九、类模板案例 一、类模板 …

SpringBoot - SpringBoot手写模拟SpringBoot启动过程

依赖 建一个工程&#xff0c;两个Module: 1. springboot模块&#xff0c;表示springboot框架的源码实现 2. user包&#xff0c;表示用户业务系统&#xff0c;用来写业务代码来测试我们所模拟出来的SpringBoot 首先&#xff0c;SpringBoot是基于的Spring&#xff0c;所以我…

3DMAX初级小白班第一课:菜单栏介绍

基本介绍 这里不可能一个一个选项全部教给大家&#xff08;毕竟之后靠实操慢慢就记住了&#xff09;&#xff0c;只说一些相对需要注意的设置。 自定义-热键编辑器-热键设置 这里有你所需要的全部快捷键 自定义-自定义UI启动布局 将UI布局还原到启动的位置 自定义-通用单…

使用Go发送HTTP GET请求

在Go语言中&#xff0c;我们可以使用net/http包来发送HTTP GET请求。以下是一个简单的示例&#xff0c;展示了如何使用Go发送HTTP GET请求并获取响应。 go复制代码 package main import ( "fmt" "io/ioutil" "net/http" …

HCIP网络的类型

一.网络类型&#xff1a; 点到点 BMA&#xff1a;广播型多路访问 -- 在一个MA网络中同时存在广播&#xff08;泛洪&#xff09;机制 NBMA&#xff1a;非广播型多路访问 -- 在一个MA网络中&#xff0c;没有泛洪机制-----不怎么使用了 MA&#xff1a;多路访问 -- 在一个…

03-常用编程概念

上一篇&#xff1a;02-编程猜谜游戏 本章介绍几乎所有编程语言中都会出现的概念&#xff0c;以及它们在 Rust 中的工作原理。许多编程语言的核心都有许多共同点。本章介绍的概念都不是 Rust 独有的&#xff0c;但我们会在 Rust 的上下文中讨论这些概念&#xff0c;并解释使用这…

课堂教学内容分为哪几类

作为一名老师&#xff0c;每天都要面对各种类型的学生&#xff0c;而学生们最关心的问题之一就是&#xff1a;老师&#xff0c;你到底要教我们什么&#xff1f;这个问题看似简单&#xff0c;实则深奥。那么&#xff0c;课堂教学内容究竟分为哪几类呢&#xff1f;今天&#xff0…

【webrtc】GCC 7: call模块创建的ReceiveSideCongestionController

webrtc 代码学习&#xff08;三十二&#xff09; video RTT 作用笔记 从call模块说起 call模块创建的时候&#xff0c;会创建 src\call\call.h 线程&#xff1a; 统计 const std::unique_ptr<CallStats> call_stats_;SendDelayStats &#xff1a; 发送延迟统计 const…

【书生·浦语大模型实战营05】《(5)LMDeploy 大模型量化部署实践》学习笔记

《(5)LMDeploy 大模型量化部署实践》 课程文档&#xff1a;《LMDeploy 的量化和部署》 1、大模型部署背景 1.1 模型部署 定义 将训练好的模型在特定软硬件环境中启动的过程&#xff0c;使模型能够接收输入并返回预测结果为了满足性能和效率的需求&#xff0c;常常需要对模型…

CLion调试Nodejs源码

【环境】 macOS node-v20.11.0源码 CLion 2023.3.2 【1】下载源码 https://nodejs.org/en/download/ 【2】编译源码 解压后的目录如下 进入解压后的目录进行编译 ./configure --debug make -C out BUILDTYPEDebug -j 4需要好久… 编译成功之后在node-v20.11.0目录下会有一个…

DNS是什么?为什么需要DNS?常用的DNS记录类型有哪些?

在互联网时代&#xff0c;基本上人人都要上网&#xff0c;网络已与人们日常生活息息相关。而DNS就在我们上网的过程中扮演着重要的角色—“将网址/域名解析成 IP 地址”。那么DNS是什么&#xff1f;为什么需要DNS&#xff1f;常用的DNS类型有哪些呢&#xff1f;别着急&#xff…