C/C++编程:空类不空

末蓝、 2022-10-21 11:58 233阅读 0赞
  1. #include <iostream>
  2. class X{
  3. };
  4. class Y : public virtual X{
  5. };
  6. class Z : public virtual X{
  7. };
  8. class A : public Y, public Z{
  9. };
  10. int main() {
  11. printf("%d, %d, %d, %d", sizeof(X), sizeof(Y), sizeof(Z), sizeof(A));
  12. }

在这里插入图片描述

在这里插入图片描述
分析:对于空类

  1. // sizeof X === 1;
  2. class X{
  3. };
  • 实际上它并不是空的,它有一个隐式的1byte,那是被编译器安插进入的一个char
  • 这使得这个类的两个object可以在内存中获得一个独一无二的地址:

    X a, b;
    if(&a == &b){

    1. printf("empty class is not empty");

    }

对于:

  1. // sizeof Y == sizeof Z == 8
  2. class Y : public virtual X{
  3. };
  4. class Z : public virtual X{
  5. };

Y和Z的大小在不同编译器不同机器上的结果是不一样的(目前是8).事实上,Y和Z的大小受到三个因素的影响:

  • 语言本身所造成的额外负担:当语言支持虚基类时,就会导致一些额外负担。在派生类中,这个额外负担反映在某种形式的指针身上,它或者指向虚基类子对象(subobject),或者指向一个相关表格:表格中存在的是虚基类子对象的地址,或者偏移量
  • 编译器对特殊情况所提供的优化处理:虚基类X子对象的1bytes大小也出现在类Y和Z身上。传统上它被放在派生类的固定(不变动)部分的尾端。某些编译器会对空虚基类提供特殊支持。(但是本机上没有这个支持)
  • 对齐的限制:大部分机器上,群聚的结构体大小会受到对齐的限制,使得它们更有效率的存取
    在这里插入图片描述
    空基类提供了一个虚拟接口,没有定义任何数据。某些新近的编译器比如vs对此提供了特殊处理。在这个策略下,一个空虚基类被视为派生类对象最开头的一部分,也就是说它并没有花费任何的额外空间。这就节省了上面第2点的1bytes(因为已经有了成员就不需要为空类再安插一个char),也就是不需要第3点的3bytes对齐填补。在这个模型下,Y和Z的大小都是4而不是8

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,233人围观)

还没有评论,来说两句吧...

相关阅读

    相关 一个的大小?

    问题源于【剑指offer】P23 1、定义一个空类型,里面没有任何成员变量和成员函数。对该类型求sizeof 结果? 结果为1 。 2、为什么不是0?  

    相关 C/C++编程优化

    C++类常为”空“,这就意味着在运行期其内部表示不耗费任何内存。这常见于只包含类型成员,非虚成员函数和静态数据成员的类,而非静态数据成员、虚函数和虚基类会在运行期耗费内存 即

    相关 的大小

    一、类的大小是类中所有成员变量大小之和,而且像结构体一样要遵循内存对齐的规则。 内存对齐原因是用空间换时间的做法,CPU将内存看做一块一块的,一块可以是2、4、8、16个字节