【发布时间】:2021-07-05 15:20:56
【问题描述】:
这是我的理解:
在虚拟继承期间,:virtual base{} 派生类连同继承的数据成员必须保留 vpointer(以跟踪 base 的成员以保留单个成员实例),并且每个虚拟继承 base 的继承层次结构有一个 vpointer出现在derived 班级中。
在此代码中具有此知识:
- sizeof(B) 和 sizeof(C) 应该是 = sizeof(A) + vptr
- sizeof(D) 应该是 = sizeof(A) + vptr_from_B + vptr_from_C
struct A{
int i=3,j=1,k=2;
};
struct B: virtual A{};
struct C: virtual A{};
struct D:B,C{};
int main()
{
std::cout<<"size of class D = "<<sizeof(D)<<"\n";
std::cout<<"size of class C = "<<sizeof(C)<<"\n";
std::cout<<"size of class B = "<<sizeof(B)<<"\n";
std::cout<<"size of class A = "<<sizeof(A)<<"\n";
return 0;
}
案例1:
结构 A{};空结构
D = 16 , C = 8 , B = 8 , A = 1
案例2:
结构 A{ int i = 3; };一个整数
D = 24 , C = 16 , B = 16 , A = 4
- 为什么 B、C 和 D 有额外的 4 个字节?
案例3:
结构 A{ int i = 3, j = 1; };两个整数
D = 24 , C = 16 , B = 16 , A = 8
- 现在 B、C 和 D 的大小保持不变,即使 A 的 sizeof 增加了 4 个字节,...?
案例4:
结构 A{ int i = 3, j = 1, k = 2};三个整数
D = 32 , C = 24 , B = 24 , A = 12
- 像 Case1 一样,我们又多了 4 个字节?
模式继续。 . . 感觉就像某种零填充来保持虚拟继承的派生类的大小为 8 的倍数,我不知道到底发生了什么以及为什么?
抱歉提前提出愚蠢的问题
【问题讨论】:
-
您不应依赖可预测的班级规模。它们的存储是特定于实现的。任何“为什么”的问题都应该被认为是毫无意义的。
-
Data structure padding 是保持对象与处理器架构字长对齐的常见做法。
-
当对象存储在数组中时,需要填充以保持 8 字节指针与 8 对齐。
-
填充和对齐是一个实现细节,可能取决于也可能不取决于性能,也可能是硬件要求。应该有很多重复在谈论这些。
-
你的感觉是对的。在您的平台上,指针似乎需要或更喜欢 8 字节对齐。如果不对齐(尽管会降低性能)或者不对齐(segv 崩溃),它们可能会很好。 C++ 倾向于更喜欢性能,即使它会在对象中造成一点填充。
标签: c++ vtable virtual-inheritance