You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承成员的访问权限是否会影响C++类的整体大小?

问题:类成员访问权限为何会影响sizeof的结果?

运行以下C++代码时,base类和派生类c1的sizeof结果均为32:

#include "iostream"
#include "string"

using namespace std;

class base{
//public:
    int a;
    double b;
    void * c;
    char d;
};

class c1 :  base{
//public:
    int a;
};

int main() {
    cout << sizeof(base) << endl;
    cout << sizeof(c1) << endl;
    return 0;
}

但取消base类和c1类中public:的注释后,派生类c1的sizeof结果变为40。该现象可在GCC中复现,请问为何成员变量的访问权限会影响类的整体大小?


解答

这是GCC编译器针对类内存布局的访问控制区段优化规则导致的,核心逻辑和内存对齐、访问区段的划分有关:

1. 先看base类的大小计算(64位系统下)

base的成员依次是:

  • int a:占4字节
  • double b:占8字节,因对齐要求,a后面要填充4字节才能对齐到8字节的起始地址
  • void* c:占8字节,无需额外填充
  • char d:占1字节,后面需要填充7字节,让整个类的大小对齐到最大成员的对齐单位(8字节)

加起来总大小是:4+4(填充)+8+8+1+7(填充)=32字节,这就是sizeof(base)=32的原因。

2. 默认私有继承+同访问区段的情况

当base和c1的成员都默认是private时:

  • c1继承base是私有继承(类默认继承权限为private),基类的所有成员在c1里都属于private区段
  • c1自己的int a也是private成员,和基类继承来的成员属于同一个访问控制区段

GCC会对同一区段的成员做紧凑布局优化:把c1的int a直接塞进base末尾的7字节填充空间里,不需要额外占用空间,所以sizeof(c1)还是32字节。

3. 开启public:后的情况

取消public:注释后:

  • base的成员变为public,但c1默认私有继承base,所以基类的public成员在c1里会被降级为private区段
  • c1自己的int a是public成员,属于单独的public区段

GCC对不同访问控制区段的成员会分开布局,而且区段之间要按照最大对齐单位(8字节)填充:

  • 第一个区段是继承自base的32字节内容
  • 第二个区段是c1的int a(4字节),后面需要填充4字节来对齐到8字节
  • 总大小就是32+4+4=40字节

简单说:同一访问区段的成员可以共享填充空隙,不同区段则必须分开占空间,这就是访问权限影响类大小的核心原因。


内容的提问来源于stack exchange,提问作者PkDrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 04:40:15