类继承基类且首成员也继承同一基类,为何是标准布局但地址不等?
问题解答
1. Derived3属于标准布局类吗?
是的,Derived3完全符合C++标准中标准布局类的定义,编译器判定其为标准布局类是正确的。
C++标准对标准布局类的核心要求包括:
- 所有非静态成员具有相同的访问控制(示例中所有成员均为
public) - 没有虚函数、虚基类
- 所有非静态数据成员本身都是标准布局类型(
Derived1是标准布局类,int是基本标准布局类型) - 继承结构满足规则:要么只有一个基类包含非静态数据成员且派生类无,要么基类都无数据成员且派生类有(这里
Base是空类,Derived3的非静态成员是Derived1和int,符合要求)
2. 为什么&d和&d.c地址不相等?
你对标准布局类的特性理解存在偏差:“标准布局对象地址与其首个成员地址相等”的结论,仅在不存在空基类优化冲突的情况下成立。
具体到你的代码场景:
Base是空类,Derived1继承Base时,编译器会触发空基类优化(EBO):空基类的子对象不占用额外空间,因此Derived1的大小等于sizeof(int),且Derived1对象的地址与其内部Base子对象的地址完全重合。- 但
Derived3同时继承Base,且第一个成员是Derived1(内部也包含一个Base子对象)。如果编译器对Derived3的Base基类也做EBO,会导致Derived3的Base子对象和Derived1的Base子对象地址完全相同——而C++标准明确规定不同的对象不能拥有相同的地址,因此编译器必须给Derived3的Base基类分配1字节的占位空间,避免地址重叠。
这就导致Derived3对象的地址(即其Base基类子对象的地址)和第一个成员d.c的地址之间差了1字节,但这并不影响Derived3的标准布局属性。
验证补充
你可以打印各类型的大小来直观感受内存分配情况:
cout << "sizeof(Base): " << sizeof(Base) << endl; cout << "sizeof(Derived1): " << sizeof(Derived1) << endl; cout << "sizeof(Derived3): " << sizeof(Derived3) << endl;
典型输出(因内存对齐规则可能略有差异):
sizeof(Base): 1 sizeof(Derived1): 4 sizeof(Derived3): 12
内容的提问来源于stack exchange,提问作者olist
相关产品推荐
相关产品推荐

