C++ 面试宝典之:空类大小究竟是不是 0?

以下内容为本人的学习笔记,如需要转载,请声明原文链接 微信公众号「ENG八戒」mp.weixin.qq.com/s/pD4bIjX2k...

首先,空类是什么?空类指的是不包含任何数据成员的类,但可能包含方法成员。

实例化时,对象需要分配存储空间用于存放数据成员,数据成员的大小和数量决定了对象的大小。如果一个类不包含任何的数据成员,那么实例化的时候应该不需要这些多余的空间。

但是实例化对象的存储空间唯一代表该对象,相应的空间地址也应该是唯一的。如果类实例化时没有分配空间,空间地址也无法确定,那么这个对象如何被识别和访问?

同一个类可以被多次实例化,也就是创建多个对象,每次实例化的对象应该是不同的,那么对应的存储空间位置也是不同的。如果地址重复说明该对象应该是同一个。

为了区分对象是否是同一个,一般通过地址来比较。下面来看看定义一个空类,分别创建两个实例对象,测试对比地址是否一致:

c 复制代码
class test { };

int main()
{
  test a, b;
  if (&a == &b)
    std::cout << "impossible: report error to compiler supplier" << std::endl;

  test* p1 = new test;
  test* p2 = new test;
  if (p1 == p2)
    std::cout << "impossible: report error to compiler supplier" << std::endl;

  return 0;
}

如果空类对象的大小为 0,那么分配的存储空间就会重叠,地址也会一样。但是上面的例程编译后实际运行结果没有输出任何信息,可见同一个空类的不同实例的地址不同,也就是说这个时候的空类的对象也会占用空间,为什么呢?

因为编译器需要区分空类的实例,所以强制给它分配了冗余的空间,这样创建空类实例返回的地址才会不一样,而且类实例化可以保留的最小内存量是 1 个字节。所以,直接实例化空类,对象大小为 0。

派生后优化

同时,如果用空类去派生新类,并且派生类存在数据成员时,派生类实例化的对象大小会受到基类的冗余空间影响吗?

ini 复制代码
class derive : public test {
  int a;
  // ...
};

int main()
{
  derive p;
  void* p1 = &p;
  void* p2 = &p.a;
  if (p1 == p2)
    std::cout << "nice: good optimizer";

  return 0;
}

编译执行上面的程序

bash 复制代码
nice: good optimizer

从输出信息来看,p.a 的地址和 p 的地址一样,可见空类 test 的派生类 derive 实例化后对象大小没有了基类对象原有的冗余空间,也就是空类这个时候真的不再占用空间。这要归功于编译器的优化处理,由于派生类存在数据成员,所以派生类实例化的对象大小会被优化,不再为基类分配冗余空间。

相关推荐
jimy14 小时前
虚函数vtable,链接时看到构造函数,linker把符号地址写入vtable(三)
开发语言·c++
潼心1412o5 小时前
C++初阶(长期更新)第9讲:string(上)
开发语言·c++
朝朝辞暮i5 小时前
C++ 第 39 章: 阶段性总复习——类、对象、构造、继承、this、指针与智能指针
开发语言·c++·算法·ros2
wuminyu5 小时前
Virtual Thread重投递至ForkJoinPool任务队列过程解析
java·linux·c语言·jvm·c++
All for pursuit.6 小时前
【回溯-6】79.单词搜索
数据结构·c++·算法·leetcode
Benny_Tang6 小时前
AT_arc180_d [ARC180D] Division into 3 题解
数据结构·c++·算法
殷色玫瑰6 小时前
C++ STL:stack、queue、priority_queue 与容器适配器详解
java·开发语言·数据结构·c++·算法·visualstudio
努力努力再努力wz7 小时前
【CUDA入门系列】CUDA编程实战:设备选择、显存管理、Kernel、Stream 与 Event 全流程梳理
开发语言·c++
沫璃染墨7 小时前
《从零入门Linux系统篇(五十八):线程篇·十一——线程安全与死锁详解:从可重入到多锁管理》
linux·服务器·开发语言·c++·驱动开发·安全·架构
郝学胜_神的一滴7 小时前
C++ Templates 05:那些容易踩坑的技巧性基础知识
c++·visual studio