C++【对象模型】

2023-11-04

索引

C++【对象模型】| 【01】简单了解C++对象模型的布局
C++【对象模型】|【02】构造函数何时才会被编译器自动生成?
C++【对象模型】|【03】拷贝构造是如何工作的,何时才会用到呢?
C++【对象模型】 | 【04】程序在内部被编译器如何转化?
C++【对象模型】 | 【05】类与类之间各种关系下对数据成员的存取、绑定、布局
C++【对象模型】| 【06】类中各种函数的刨析
C++【对象模型】| 【07】构造、析构、拷贝做了哪些事?
C++【对象模型】| 【08】类在执行期会处理哪些事呢?
C++【对象模型】| 【09】类模板、异常处理及执行期类型识别

一、默认构造函数

1、何时默认构造函数会自动生成

当类没有提供默认构造时,如果编译器需要它,则将会为其添加上;如果是程序的需要,则需要我们手动为它添加;
- 并不是没有声明默认构造时,编译器就自动生成;只在编译器真正需要的时候;

如何区分编译器需要还是程序需要

当使用`foo f;`创建一个对象时,
- 【编译器】由于类中没有提供默认构造函数,编译器会自动为其生成使之能被创建成功;
- 【程序】类中的数据成员初始化交给构造函数,当想要默认的构造函数能够初始化数据成员(a)时,则我们需要手动提供;
class foo{
public:
	void func(); 
private:
	int a;
}

2、编译器合成有用的构造函数四种情况

2.1 类中内含带有默认构造的类成员

当一个类内含一个类成员(带默认构造),此时编译器需要为类合成一个默认构造函数(在真正需要被调用时才发生);
class B{}
class A{ 
private:
	B b;
}

编译器(不同的文件)如何避免合成多个默认构造?

其编译器合成的函数都是按内联的方式完成,具有静态链接,不会被文件外使用、看到;

案例

class Foo { public: Foo(), Foo(int) }
class Bar { public: Foo foo; char *str; }

void func() {
	Bar bar;
}
【如果没有Bar没有提供默认构造】
当创建一个Bar对象时,由于内含一个Foo成员,其foo必须要在它构造的时候初始化;
而Bar没有提供默认构造,故编译器需要为它生成一个能够调用Foo的默认构造来处理成员Bar::foo;【编译器责任】
但生成的默认构造不为str做初始化【程序员责任】
===> 编译器合成的默认构造
inline Bar::Bar() { foo.Foo::Foo() }

【如果Bar提供默认构造】
====> Bar::Bar() { str = 0; }
此时程序的需求被满足,但没有对foo进行初始化提供,而此时应该有默认构造,故编译器不会再次生成默认构造;
那编译器会怎么做呢?
编译器会将初始化foo的代码插入在默认构造的用户代码前(str之前);
如果类中内含多个其他类,则将按照声明顺序将其插入;

2.2 带有默认构造的基类

【当子类没有默认构造】
当继承的基类含有默认构造时,若子类没有默认构造,则编译器会自动生成【用来调用基类的构造函数】;
【子类提供构造函数】
当子类提供构造函数但没有默认构造,则编译器会扩张每一个构造函数(添加基类的默认构造代码),不会合成新的默认构造;

【注意】成员类的调用次序在继承后;
class A{
public:
    A() { cout << "A" << endl; }

    ~A() { cout << "~A" << endl; }
};

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

class C : public A{
public:
    C() { cout << "C" << endl; }
    C(int v) {}
private:
    B b;
};

int main() {
    C c;
    cout << "------------" << endl;
    C cc(1);
    cout << "------------" << endl;
    return 0;
}

在这里插入图片描述

2.3 带有虚函数的类

- 当class声明/继承一个virtual function;
- 当class派生自一个继承串链,其中一个或更多的virtual base classes;
以上两种情况也会合成virtual constructor;
由于虚函数是通过虚表来进行存放,而虚表通过类中的vptr存储该地址,发生在编译期间,编译器必须给vptr设定初值,且放
置地址,这些都在构造函数中完成,故当函数有以上两种情况时,编译器会合成;

2.4 带有一个虚基类的类

编译器必须让虚基类在每个子类中的位置,能够在执行期准备好,在编译期不能够确定真正的类;
编译器会在构造中安插允许虚基类的执行器存取操作代码,故若没有构造函数,则编译器会自动合成;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++【对象模型】 的相关文章

  • 使用 CLion 进行 OpenCV Windows 设置

    我想在 Windows 上为 CLion IDE 设置 OpenCV 我尝试使用 OpenCV 3 1 和 2 4 得到相同的结果 我有 Windows 10 64 位 CLion 使用 cygwin 环境 到目前为止我做了什么 1 从Op
  • 多个源的 makefile

    在学习 make 文件时 我试图为多个源目录编写一个 make 文件 似乎我在某个地方错了 这是我的代码结构 directory common fun2 c inc fun h src fun1 c main c 这是我的生成文件 CC c
  • 在现代 C++ 中,临时生命周期延长何时有用?

    在 C 中 您可以将函数的返回值 返回值 而不是引用 绑定到 const 引用 并且代码仍然有效 因为该临时对象的生命周期将延长到作用域末尾 例如 std string get string return abc void f const
  • CSharpRepl emacs 集成?

    我碰巧知道莫诺CSharpRepl http www mono project com CsharpRepl 是否有 emacs csharp 模式使用它在一个窗口中运行 REPL 并像 python 模式一样在另一个窗口中编译 运行 C
  • 是否存在指向不同类型的指针具有不同大小的平台?

    C 标准允许指向不同类型的指针具有不同的大小 例如sizeof char sizeof int 是允许的 但是 它确实要求如果将指针转换为void 然后转换回其原始类型 它必须与其原始值进行比较 因此 从逻辑上来说 sizeof void
  • 检测到堆栈崩溃

    我正在执行我的 a out 文件 执行后 程序运行一段时间 然后退出并显示消息 stack smashing detected a out terminated Backtrace lib tls i686 cmov libc so 6 f
  • C# 5 async/await 线程机制感觉不对?

    为什么让调用线程进入异步方法直到内部 等待 一旦调用异步方法就生成一个线程 这不是更干净吗 这样您就可以确定异步方法会立即返回 您不必担心在异步方法的早期阶段没有做任何昂贵的事情 我倾向于知道某个方法是否要在 我的 线程上执行代码 不管是堵
  • 计算另一个表达式中的 C# 表达式

    我想在另一个表达式中使用一个表达式 Expression
  • 在 omp 并行 for 循环中使用 unique_ptr 会导致 SEG.FAULT

    采取以下代码 include
  • 根据对象变量搜索对象列表

    我有一个对象列表 这些对象具有三个变量 ID 名称和值 这个列表中可能有很多对象 我需要根据ID或Name找到一个对象 并更改值 例子 class objec public string Name public int UID public
  • 引用/指针失效到底是什么?

    我找不到任何定义指针 引用无效在标准中 我问这个问题是因为我刚刚发现 C 11 禁止字符串的写时复制 COW 据我了解 如果应用了 COW 那么p仍然是一个有效的指针并且r以下命令后的有效参考 std string s abc std st
  • 如何从 Rx Subscribe 回调异步函数?

    我想回调 Rx 订阅中的异步函数 例如 像那样 public class Consumer private readonly Service service new Service public ReplaySubject
  • 英文日期差异

    接近重复 如何计算相对时间 https stackoverflow com questions 11 how do i calculate relative time 如何在 C 中计算某人的年龄 https stackoverflow c
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • 在 OpenGL 中渲染纹理 1 到 1

    所以我想做的是使用 OpenGL 和 C 将纹理渲染到平面上 作为显示图像的一种方式 但是我需要确保在渲染纹理时没有对纹理进行任何处理 抗锯齿 插值 平滑 模糊等 这是 OpenGL 处理渲染纹理的默认方式吗 或者是否需要设置一些标志才能禁
  • 逆向工程 ASP.NET Web 应用程序

    我有一个 ASP NET Web 应用程序 我没有源代码 该 bin 包含 10 个程序集和一个 compiled 文件 我在 App Code dll 上使用 Reflector 它向我显示了类和命名空间之类的东西 但它太混乱了 有没有什
  • 选择查询不适用于使用Parameters.AddWithValue 的参数

    C 中的以下查询不起作用 但我看不出问题所在 string Getquery select from user tbl where emp id emp id and birthdate birthdate cmdR Parameters
  • 使用 jQuery 从 ASP.Net JSON 服务获取数据

    我正在尝试调用 Google 地图地理编码 API 从纬度 经度对中获取格式化的地址 然后将其记录到控制台 我正在尝试获取为给定位置返回的第一个 formatted address 项目 我很简单无法从 JSON 中提取该项目 我不知道为什
  • 来自 3rd 方库的链接器错误 LNK2019

    我正在将旧的 vc 6 0 应用程序移植到 vs2005 我收到以下链接器错误 我花了几天时间试图找到解决方案 错误LNK2019 无法解析的外部符号 imp 创建AwnService 52 在函数 public int thiscall
  • 如何将 SQL“LIKE”与 LINQ to Entities 结合使用?

    我有一个文本框 允许用户指定搜索字符串 包括通配符 例如 Joh Johnson mit ack on 在使用 LINQ to Entities 之前 我有一个存储过程 该存储过程将该字符串作为参数并执行以下操作 SELECT FROM T

随机推荐

  • 计算机丢失disrupt,disrupt造句

    1 In mice the pathogen Citrobacter rodentium can disrupt this layer and cause inflammation and diarrhea 2 Women interrup
  • 指针定义(一级指针和二级指针)以及内存四区

    1 一级指针 1 定义 类型 指针变量名 变量 Int p a 地址 地址是内存的位置编号 是常量不可以修改 指针 一般指指针变量 用来存放地址的 是可以被修改的 2 二级指针 指向一级指针 保存的是一级指针的地址 Int p x int
  • 深搜(dfs)和广搜(bfs)

    深搜 dfs 和广搜 bfs 广搜可以用来解决最小路径问题和连通性问题 深搜可以解决连通性问题 实现方式 深搜用函数递归实现 广搜用队列实现 问题 输入地图判断连通性和最小路径 每次只能走上下左右 S为起点 T为终点 为障碍物 可以走 如以
  • Dart 2.18 正式发布

    互操作性增强 平台特定的网络组件 优化类型推断 以及空安全语言里程碑的近期更新 文 Michael Thomsen Google Flutter Dart 产品经理 Dart 2 18 稳定版也随着 Flutter 3 3 稳定版一起发布
  • 智能车制作——速度环PID

    做了智能车写这个做个记录 各位大佬勿喷 PID控制器 PID 控制器 比例 积分 微分控制器 是一种通过控制系统的偏差来调整输入信号的线性反馈控制算法 通俗的说 它可以给出使执行器 电机 快速准确到达目标的 指导方案 反馈 反馈是指将系统输
  • 基于深度学习和自闭症脑成像数据库(ABIDE)识别自闭症谱系障碍

    ASD是一种以大脑为基础的疾病 其特征是社会缺陷和重复行为 根据美国疾病控制中心最近的数据 美国68名儿童中就可能有1名患有自闭症 本研究的目的是基于深度学习算法从大型脑成像数据集中识别自闭症谱系障碍 ASD 患者 本文调查了一个ASD患者
  • Java代码之JDBC实现数据库之间定时的表格传输(由一个库读取到另一个库)实例

    本代码主要是JDBC和Java定时器 注释很详细 希望对大家有用 有什么不明白的可以在评论处留言 共同探讨 package first import java sql Connection import java sql DriverMan
  • R语言深度学习:强化学习入门

    专栏内含有很多案例供参考 目录 1 强化学习基础 2 强化学习的一个简单例子 玩游戏 结论 在今天的博客中 我们将一起探索强化学习 Reinforcement Learning 的世界 强化学习是深度学习的一个重要领域 它让机器通过与环境的
  • 多层Unity3D物体模型穿透问题处理

    本文针对在一个界面中展示多层3D物体时遇到的模型穿透问题提出一些解决方案 如图 当我们想要在同一个界面中展示两层或以上3D物体时 有时会因为第一层物体材质上的 shader 渲染深度被破坏或其它原因导致第一层的物体穿透到第二层界面上来了 在
  • FTP-----局域网内部远程桌面

    此文包含详细的图文教程 有疑问评论区留言 博主第一时间解决 目录 一 被远程桌面的电脑 1 开启远程权限 2 添加账户 有本地账户跳过这步 3 帐号隶属于 远程桌面 4 帐号隶属于 本地用户组 二 本地电脑连接远程桌面 前提条件 1 两台电
  • 蚁剑jsp一句话木马

    参考链接 https github com yzddmr6 JspForAntSword 密码为 passwd
  • 【深度学习图像识别课程】keras实现CNN系列:(5)应用数据增强进行CIFAR10分类

    一 图像增强简介 如何保证图像的标度不变性 大小 平移不变性 位置 旋转不变性 角度 最大池化层 保证平移不变性 增强 训练集扩展 对训练图片进行随机旋转或者平移 保证平移不变性 旋转不变性 避免过拟合 keras文档 https kera
  • spark集群8080端口页面只显示master的情况

    电脑配置是一台物理机作为master 一台物理机作为slave 在master启动运行后 使用jps命令分别查看两台机器的运行状况 master与slave均运行正常 但是进入master 8080的web控制端查看运行状态时候 发现只有m
  • 写一个python函数 用cuda加速

    好的 下面是一个用 CUDA 加速的 Python 函数的示例 import numpy as np import cupy as cp def accelerate with cuda x y 将 numpy 数组转换为 cupy 数组
  • 【视觉slam十四讲笔记】Sophus库的使用

    Sophus库的使用 include
  • Day03 Python之 可迭代对象Iterable和迭代器Iterator、迭代器协议

    一 什么是可迭代对象 iterable 1 可迭代对象 iterable 可以通过for in 这类语句遍历读取数据的对象 如 列表 字符串 元组 字典 集合 2 for循环工作原理 在内部对可迭代对象调用iter 方法 获取到迭代器对象
  • 02_ue4界面介绍

    1 菜单栏 1 文件 加载保存项目和关卡等 2 编辑 项目设置 标准的复制和粘贴操作 3 窗口 打开视图和其他面板 如果不小心关了窗口 可以在里面找 4 帮助 获得在线文档等帮助 2 工具栏 快速访问常用工具 1 保存当前关卡 2 对当前关
  • Flink 水位线

    水位线是什么 窗口 有了 但是要知道我们面对的是实时数据 而这些数据随时会出现延迟的情况 从几秒到几小时都有可能 如果要忽略这些数据 那么显然对于结果的计算是不准确的 可是要等待这些延迟数据的话 那岂不是等同于批处理了 我们等不了那么久的
  • CentOS7上安装 Apache

    在 CentOS 7 上安装 Apache 的方法如下 1 首先打开终端 并使用 sudo 命令以 root 权限运行 sudo su 2 更新软件包列表 yum update 3 安装 Apache 服务器和常用工具 yum instal
  • C++【对象模型】

    文章目录 索引 一 默认构造函数 1 何时默认构造函数会自动生成 2 编译器合成有用的构造函数四种情况 2 1 类中内含带有默认构造的类成员 2 2 带有默认构造的基类 2 3 带有虚函数的类 2 4 带有一个虚基类的类 索引 C 对象模型