使用空类的虚拟继承
Virtual inheritance using empty classes
谁能说出以下代码在C++中输出的确切原因?我收到的代码输出包含在标题注释中。它与虚拟表和 v 指针有什么关系。
/* sizeof(Empty) 1
sizeof(Derived1) 1
sizeof(Derived2) 8
sizeof(Derived3) 1
sizeof(Derived4) 16
sizeof(Dummy) 1
*/
#include <iostream>
using namespace std;
class Empty
{};
class Derived1 : public Empty
{};
class Derived2 : virtual public Empty
{};
class Derived3 : public Empty
{
char c;
};
class Derived4 : virtual public Empty
{
char c;
};
class Dummy
{
char c;
};
int main()
{
cout << "sizeof(Empty) " << sizeof(Empty) << endl;
cout << "sizeof(Derived1) " << sizeof(Derived1) << endl;
cout << "sizeof(Derived2) " << sizeof(Derived2) << endl;
cout << "sizeof(Derived3) " << sizeof(Derived3) << endl;
cout << "sizeof(Derived4) " << sizeof(Derived4) << endl;
cout << "sizeof(Dummy) " << sizeof(Dummy) << endl;
return 0;
}
首先,即使没有成员的类也必须具有非零大小。标准坚持这一点。否则,指针算术和数组将无法工作,因为零大小类的数组将在其所有元素位于同一位置!
其他尺寸不同的事实很可能是由于对向表造成的。但这在标准中没有明确规定,因此是编译器处理事物的方式的表现。
另请注意,多态性要求在基类中至少定义一个虚拟方法。这说明sizeof(Derived1)
的大小与基类相同。
大小的差异是由于编译器添加vptr
。
sizeof(Derived1) = 1
,这是因为根据C++标准,空类总是占用1字节的内存。
sizeof(Derived2) = 8
,由于它继承了虚拟基类 Derived1,所以编译器(sizeof(vptr) = 8
在 64
位机器上(添加了一个 vptr 因此sizeof(Derived2)
显示 8 个字节。
sizeof(Derived3) = 1
因为 1 个字节的char
。
sizeof(Derived4) = 16
,虚拟继承的内部实现完全依赖于编译器,因此您会看到 16 字节作为大小。
sizeof(Dummy) = 1
因为它包含一个字符实体。
Empty
的大小为 1,因为每个对象的大小必须至少为 1。
出于同样的原因,Derived1
的尺寸为 1。
Derived2
的大小为 8,因为编译器需要 8 个字节来进行虚拟继承(可能是一个指针(。
Derived3
的大小为 1,因为编译器已应用"空基类"优化。
Derived4
的大小为 16,因为虚拟继承所需的 8 个字节使对象需要 8 字节对齐。
Dummy
的大小为 1,因为这是char
的大小。
- 大小虚拟继承中的派生类
- C++ 多级虚拟继承编译问题
- 如何正确获得虚拟继承?
- 避免C++虚拟继承
- 虚拟继承基构造函数消除
- 虚拟继承中是否存在多重继承?
- 了解虚拟继承类 vtables 和 vptr 创建
- 当键是虚拟继承中涉及的基类指针时,对 std::unordered_map 项的访问崩溃
- 我是否需要在虚拟继承类的构造函数中初始化基类以解决菱形继承问题?
- C++ 不明确访问 - 虚拟继承
- 虚拟继承中来自基数的虚拟调用
- 虚拟继承:调用没有匹配函数
- 虚拟继承的内部机制
- 联合虚拟继承
- C++虚拟继承类的大小
- C++虚拟继承、虚拟析构函数和 dynamic_cast<void*>
- 虚拟继承构造函数的组装
- 虚拟继承情况下类的意外大小
- 虚拟继承情况下的 vtable
- C++解决没有虚拟继承的钻石继承问题