C++ 虚拟继承情况下类的大小
有人能解释一下在涉及虚拟函数的虚拟继承的情况下类的大小吗C++ 虚拟继承情况下类的大小,c++,polymorphism,virtual,C++,Polymorphism,Virtual,有人能解释一下在涉及虚拟函数的虚拟继承的情况下类的大小吗 class A{ char k[ 3 ]; public: virtual void a(){}; }; class B : public A{ char j[ 3 ]; public: virtual void b(){}; }; class C : p
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)
sizeof(C)
比sizeof(B)
更重要,因为C类型的对象(因为它实际上从A继承)将包含指针(除了vptr之外,B类型的对象也将包含)Scott Meyers在其书的第24项“了解虚拟函数、多重继承、虚拟基类和RTTI的成本”中详细解释了它从A.Scott Meyers继承的部分(约10页)以下是我对所有字节的使用位置的最佳猜测:
Avptr Bvptr CVptr DVptr k j i h k' j' i' TOTAL
============= ========================================= =====
sizeof(A): 8 4 4 8
sizeof(B): 12 4 4 4 12
sizeof(C): 16 4 4 4 4 16
sizeof(D): 32 4 4 4 4 4 4 4 4 32
其中:
- VPTR每个占用4个字节(64位指针)
- 字符数组每个占用4个字节(为了对齐而向上舍入)
- k',j'和i'是通过C而不是B继承的变量的副本
struct A {};
struct B : virtual A {};
struct C : virtual A {};
struct D : B, C {};
当完整类型为AB
时,A
相对于B
对象开始的位置可以不同于B
的A
子对象作为最终对象D
的一部分时的位置。如果这不明显,则假设相对位置相同,并检查C
最终对象中A
相对于C
的相对位置或D
中的C
子对象的相对位置是否也可以维护
至于最后一个例子,我不太想分析它。。。但是,您可以读取C++对象模型的具体实现。所有其他实现没有太大区别
最后一个例子: 尺寸(D):32 D包含一个B子对象(12)和一个C子对象(16),再加上一个大小为3的附加数组和一个额外的填充1位 在这种特殊情况下,可能出现的问题是,如果
C
实际上从A
继承,那么为什么会有两个A
子对象,答案是虚拟基意味着对象愿意与层次结构中也愿意共享它的任何其他类型共享此基。但是在这种情况下,B
不愿意共享它的A
子对象,因此C
需要它自己的子对象
您应该能够通过向不同级别的构造函数添加日志来跟踪这一点。在
A
的情况下,让它在编译器中获取一个值,并从每个扩展类传递不同的值。将vptr的大小添加到类的大小中。有关详细信息->这些尺寸有什么让您感到惊讶?请记住,所有非空的基子对象都必须正确对齐。因此,如果你愿意,你可以考虑每个类都有一个4字节的4位成员对齐。@ FrdelsLon……我知道多态性类受虚拟指针影响的大小。但是实际上继承的效果是什么?当我们实际上继承时,有没有隐藏的指针???@DumbCoder:没那么简单。虚拟表需要Avptr
,但您需要虚拟基的额外指针。C不扩展B,因此它不包含j。额外的4个是指向子对象的指针