在虚拟继承的情况下类的大小
在涉及虚函数的虚拟继承的情况下,有人可以解释一下类的大小吗?
Can someone please explain about the size of the classes in the case of virtual inheritance involving virtual functions.
class A{
char k[ 3 ];
public:
virtual void a(){};
};
class B : public A{
char j[ 3 ];
public:
virtual void b(){};
};
class C : public virtual A{
char i[ 3 ];
public:
virtual void c(){};
};
class D : public B, public C{
char h[ 3 ];
public:
virtual void d(){};
};
类大小的输出是:
sizeof(A): 8
sizeof(B): 12
sizeof(C): 16
sizeof(D): 32
我使用的编译器是gcc 版本 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)
推荐答案
大小(A):8
数组中的 3 个字节,1 个字节填充,4 个字节用于 vptr(指向 vtable 的指针)
3 bytes in the array, 1 byte padding, 4 bytes for the vptr (pointer to the vtable)
大小(B):12
一个子对象:8 个,3 个字节用于额外数组,1 个字节填充
A subobject: 8, 3 bytes for the extra array, 1 byte padding
大小(C):16
这可能会让你感到惊讶...一个子对象:8 个,3 个字节用于额外数组,1 个字节填充,4 个字节指向 A 的指针
This is probably the surprising one for you... A subobject: 8, 3 bytes for the extra array, 1 byte padding, 4 bytes pointer to A
当你有虚拟继承时,虚拟基础子对象相对于完整类型开始的位置是未知的,因此在原始对象中添加了一个额外的指针来跟踪虚拟基础的位置.考虑这个例子:
Whenever you have virtual inheritance, the location of the virtual base subobject with respect to the start of the complete type is unknown, so an extra pointer is added to the original object to track where the virtual base is. Consider this example:
struct A {};
struct B : virtual A {};
struct C : virtual A {};
struct D : B, C {};
当完整类型为 B
时,A
相对于 B
对象开头的位置可以不同于该位置当 B
的 A
子对象是最终对象 D
的一部分时.如果这不明显,则假设相对位置相同,并检查 A
相对于 C
的相对位置是否在 C
也可以维护 D
中的最终对象或 C
子对象.
The location of A
with respect to the start of the B
object when the complete type is a B
can be different than the location of the A
subobject of B
when it is part of the final object D
. If this is not obvious, assume that the relative location is the same, and check whether the relative location of A
with respect to C
in a C
final object or a C
subobject in D
can also be maintained.
至于最后一个例子,我不太想分析它......但你可以阅读 Itanium C++ ABI 用于 C++ 对象模型的具体实现.所有其他实现没有太大区别.
As for the last example, I don't quite feel like analyzing it... but you can read the Itanium C++ ABI for a concrete implementation of the C++ object model. All other implementations don't differ much.
最后一个例子:
大小(D):32
D 包含一个 B 子对象 (12) 和一个 C 子对象 (16),加上一个大小为 3 的附加数组和一个额外的填充位 1.
D contains a B subobject (12), and a C subobject (16), plus an additional array of size 3 and one extra bit of padding 1.
在这种特殊情况下,可能会出现的问题是,如果 C
实际上继承自 A
,为什么会有两个 A
子对象,并且答案是虚拟基础意味着对象愿意与层次结构中也愿意共享它的任何其他类型共享此基础.但是在这种情况下,B
不愿意共享它的 A
子对象,所以 C
需要它自己的.
In this particular case, the question that could come up is why are there two A
subobjects if C
inherits virtually from A
, and the answer is that virtual base means that the object is willing to share this base with any other type in the hierarchy that is also willing to share it. But in this case B
is not willing to share it's A
subobject, so C
needs it's own.
您应该能够通过将日志添加到不同级别的构造函数来跟踪这一点.在 A
的情况下,让它在编译器中取一个值并从每个扩展类传递不同的值.
You should be able to track this by adding logs to the constructors at the different levels. In the case of A
have it take a value in the compiler and pass different values from each extending class.
相关文章