空类中都有哪些东西

2023-11-01

定义一个空类,里面什么内容都没有

class A
{
};

想想看,它的大小应该是多少??

要计算一个类对象的大小,要知道这么几点:

  • 类大小是非静态数据成员的类型大小之和
  • 若类中定义了虚函数,需要考虑到虚表指针也占用类对象的内存空间(32位机器下占用四字节)
  • 编译器为了提高存取效率,类大小往往会被调整为系统的整数倍,和结构体中的内存对齐类似(结构体内存对齐详情戳这里为什么要进行结构体内存对齐
  • 类大小与类的构造函数、析构函数和其他成员函数无关。

基于以上这些,理论上空类的大小应该是0,但是通过测试发现空类的大小为0。
C++标准规定类的大小不能为0,空类的大小为1,当类中不包含非静态成员变量和虚函数时,该类对象的大小也为1.

原因如下:
类的实例化是在内存中分配一块空间,每个对象在在内存中都有独一无二的地址,空类也能实例化,而空类实例化出的对象也需要一块独立空间,所以编译器会为空类隐含加一个字节,就能保证两个不同对象的地址不同。所以空类大小为1,而不是0.

空类中真的什么都没有吗??

并不见得,任何一个类中都有六个默认的成员函数,空类也不例外
六大默认成员函数分别是:

  • 构造函数
  • 拷贝构造函数
  • 析构函数
  • 赋值运算符重载
  • 取地址操作符重载
  • 被const修饰的取地址操作符重载

构造函数和析构函数在前面已经详细介绍过了,可以戳这里再温习一波构造函数和析构函数详解

在C++标准中,一个类中即使不显示给出以上这六个成员函数,编译器也会自动合成,但是由于不同的编译器都会有不同程度的优化,他们不一定在任何情况下都会合成这些成员函数,若对于一个构造函数,它既没有参数,在函数内部也不进行任何操作,合成也无任何意义,因此编译器就只会在需要的时候来合成。

以构造函数为例,编译器在那些情况下才会合成默认的构造函数??

有四种情况:
1.第一种
类A中有自己的默认构造函数,类B中没有,但是类B中包含了类A的对象,这种情况下,为了初始化B类中的A对象,编译器会为B类合成一个默认的构造函数。

2.第二种
若基类定义了构造函数,而派生类未定义构造函数,在创建派生类对象时,编译器会自动合成派生类的构造函数,目的是为了调用基类的构造函数。

这里顺便说一下继承体系下基类和派生类的构造函数/析构函数的调用次序
1.先调用派生类构造函数,再调基类构造函数;但是执行顺序相反,先执行基类的,再执行派生类的,即先构造基类的所有成员,再构造派生类成员。
2.析构函数是先调派生类的,再调基类的,后构造出来的先销毁,先销毁派生类成员,再销毁基类成员(相当于栈)。

3.第三种
在虚拟继承体系中,编译器为了将虚基表指针(基类成员变量偏移量表指针)放入派生类对象的前四个字节中,会合成构造函数。(虚拟继承了解一下

4.第四种
若基类定义了虚函数,编译器会为其派生类合成构造函数,目的是将虚表指针放入派生类对象的前四个字节。(了解多态点这里)(深入学习就看这儿


拷贝构造函数

是特殊的构造函数,创建对象时使用已存在的同类对象进行初始化编译器自动调用。

  • 函数名和类名相同
  • 参数为类对象的引用(一般用const修饰,防止修改原对象的值)

    为什么必须使用引用??
    试想一下,若此处的参数我们采用值传递,当传参时,形参是实参的一份临时拷贝,拷贝时也需要调用拷贝构造函数,所以它会一直递归调用,直到栈溢出

    • 若未显示定义,系统会自动合成默认拷贝构造函数,它会依次拷贝原对象的成员来初始化新对象。
何时会用到拷贝构造函数??
  • 用一个已存在类对象来实例化另一个同类对象
A a1;
A a2(a1);
  • 作为函数参数(传值方式)
void Fun(A a)
{}
  • 作为函数返回值(值返回方式)
A Fun()
{}

深拷贝和浅拷贝


赋值运算符重载

赋值运算符函数在定义时注意几点:
1.参数最好传引用(const修饰),可以少创建一个临时变量
2.返回值也返回引用,返回值的生命周期比函数要长
返回值不能为空,有可能还会连续赋值
3.一定要检查是否是自己给自己赋值,因为接下来的操作可能会释放空间,程序出错。

赋值运算符函数若未显示定义,系统会自动合成一个默认的赋值运算符函数,一般情况下都可以使用,但在有些情况下会出错,只要涉及资源,采用系统提供的就会有问题。
即所谓的深浅拷贝


取址运算符重载(&)

对该对象取地址,也就是this指针

类名* operator&()
{
    return this;
}

const修饰的取址运算符重载(&)

不能修改原对象
此时的this指针类型为 const 类名* const

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

空类中都有哪些东西 的相关文章

随机推荐

  • Batch与Patch 代表什么

    Batch是批量的大小 就是你训练的时候每次输入多少张图片 Patch是图像块的大小 比如说原图1024 1024 随机从图中裁剪出256 256大小的块 就是patch 更准确来说 patch 指一个二维图片中的其中一个小块 即一张二维图
  • cuda编程性能 分析工具 nvprof的使用

    ubuntu环境上 安装cuda 会自动安装一些工具nvcc nvprof nvcc gdb 1 编译生成可执行文件 2 nvprof test 可以把性能分析数据输出到文件中 nvprof test o test nvvp 可以把在nvi
  • C++的三种实例化对象方式

    一 隐式创建 class CEmployee private int age int id public CEmployee cout lt lt 这是构造函数 lt lt endl CEmployee int id this gt id
  • C++ Qt常用面试题整理(不定时更新)

    目录 1 Qt基础知识 1 Qt信号槽机制的优势和不足 2 static和const的使用 3 指针常量 常量指针 常指针常量 4 指针和引用的异同 5 如何理解多态 6 虚函数表 7 常用数据结构 8 Tcp 2 C 基础 1 C语言和C
  • react项目路由组件懒加载和路由传值方式

    项目实战 使用useRoutes配置路由 结合插槽配置用户登录检测 用户登录成功进入login 直接系统主界面 路由模块抽离 整体代码外移 path admin element
  • IGBT选型和设计注意事项

    认识IGBT IGBT 绝缘栅双极型晶体管 是由 BJT 双极型三极管和绝缘栅型场效应管 MOS 组成的复合全控型电压驱动式功率半导体器件 兼有 MOSFET 金氧半场效晶体管的高输入阻抗和电力晶体管 GTR 的低导通压降两方面的优点 具有
  • 谷歌地图-----添加文本标注

    由于谷歌地图没有直接的类似百度地图API中的BMap Label 方法 var label new google maps Marker label color FFF 文本颜色 fontSize 14px 文本字体大小 text 我的文本
  • P5[3-1]GPIO输出端口(简介+结构+配置+电路+软件设计原理)

    注 GPIO命名是GPIOA GPIOB 每个GPIO都有16个引脚 PA0 PA1 PA15 寄存器就是特殊的存储器 内核通过APB2总线对寄存器进行读写 完成输出电平和读取电平功能 每一位对应一个引脚 输出寄存器写1 对应引脚输出高电平
  • Js 正则 大于0的数

    const reg 1 9 d d 1 6 0 d 1 6 以下正则也是正确的 const reg d 1 9 0 d 1 6 0 d 1 6 大于0 小数不限 const reg 1 9 0 9 0 d 1 9 d
  • vue中使用el-table组件进行分页多选,回显、切换分页记住上一页所勾选和取消的选项

    需求 1 table表格多选 并且切换分页之后能记住上一页的选项 2 回显数据 切换分页之后再切换回来依然能回显数据 3 点击选项 未保存数据 切换页面后再切换回来初始化数据勾选状态 4 全选 取消全选数据正常变化 5 使用了dialog来
  • IDEA隐藏不想看见的文件

    比如我在使用idea创建spring boot工程时会出现图中箭头指向的文件 但是我又不想看到它们 可以通过设置将其隐藏 单击文件 打开设置 在搜索框中输入File Types然后打开 在箭头所指的地方下面的输入框中输入你要隐藏的文件名 也
  • 函数对象简述

    使用方式 函数与函数对象 函数指针与函数对象 使用方式 函数对象 简而言之 就是类对于 运算符的重载 使我们可以像使用函数那样使用对象 示例如下 ifndef TOOBIG H define TOOBIG H template
  • 【完全开源】小安派-Audio 外置音频开发板

    目录 一 概述 二 系统框图 三 电源管理模块 四 外置语音模块 五 GPIO引脚设计 六 资料 一 概述 小安派 Audio AiPi Audio 是安信可团队专门为Ai M61 32S设计的音频驱动开发板 搭配BL618芯片 其外置ES
  • PyCharm中导入库的方法

    两种方法 1 搜索添加 列表中是已经存在的库 若需要添加库 点击 搜索 待库安装完成 即可使用 2 利用终端命令 输入代码 回车 即可完成 numpy库为例 我的是已经存在了
  • 【抽样技术】CH2 简单随机抽样

    目录 前言 一 定义 二 概述 1 总体 2 单元 3 抽样比 4 样本抽取原则 5 在抽样理论中的地位与作用 三 参数估计 1 参数表示 2 对总体特征的估计思路 3 对总体均值的估计 1 引理 2 对总体均值的估计 4 方差和协方差的估
  • ROS2学习笔记(三)从turtlesim学习ROS2主题

    从turtlesim学习ROS2主题 前言 学习ROS2的路 并不能通过学习ROS1代替 因为ROS2的 内核 不同于ROS1 必须认认真真从头开始重新学习 Ubuntu版本 20 04 ROS版本 Foxy 学习笔记回顾 ROS2学习笔记
  • Teamviewer检测为商业用途的解决方案

    Teamviewer检测为商业用途的解决方案 注意 Teamviewer远程链接需要两台计算机参与 需要在两台计算机上都安装Teamviewer软件 所以在链接中出现被检测到商业用途 并不知道到底是哪一台计算机上的电脑出现问题 所以如果按照
  • solr之lucene全文检索的基本原理

    一 总论 根据http lucene apache org java docs index html定义 Lucene是一个高效的 基于Java的全文检索库 所以在了解Lucene之前要费一番工夫了解一下全文检索 那么什么叫做全文检索呢 这
  • 从零开始学matplotlib画图(三): 堆积图

    堆积图常用于综合展示不同分类的指标趋势以及它们的总和的趋势 比如说 我们想看一下过去二十年来中国人口总量的变化趋势 同时 我们又想看一下男 女性人口各自的变化趋势 甚至我们还想看一下它们各自占比的变化趋势 这时 我们就可以用堆积图来更高效
  • 空类中都有哪些东西

    定义一个空类 里面什么内容都没有 class A 想想看 它的大小应该是多少 要计算一个类对象的大小 要知道这么几点 类大小是非静态数据成员的类型大小之和 若类中定义了虚函数 需要考虑到虚表指针也占用类对象的内存空间 32位机器下占用四字节