gpt4 book ai didi

c++ - 了解虚拟派生类的大小

转载 作者:行者123 更新时间:2023-12-05 08:30:10 25 4
gpt4 key购买 nike

#include <iostream>
using namespace std;
class A {
int a;
};
class B1 : virtual public A {
int b1;
};
class B2 : virtual public A {
int b2;
};
class C : public B1, public B2 {
int c;
};

int main() {
A obj1; B1 obj2; B2 obj3; C obj4;
cout << sizeof(obj1) << endl;
cout << sizeof(obj2) << endl;
cout << sizeof(obj3) << endl;
cout << sizeof(obj4) << endl;
return 0;
}

输出:

4
16
16
40

在上面的c++程序中,A 的大小是 4 因为它只有一个 intB1 的大小为 16,因为 (int+ int + virtual pointer) B2 相同

但是C的大小怎么是40???

最佳答案

结果可能因您使用的编译器和系统架构而异。例如,msvc 19.28 x64 给出了这个不言自明的结果(使用选项 /d1reportAllClassLayout 得到它):

class C size(44):
+---
0 | +--- (base class B1)
0 | | {vbptr}
8 | | b1
| | <alignment member> (size=4)
| | <alignment member> (size=4)
| +---
16 | +--- (base class B2)
16 | | {vbptr}
24 | | b2
| | <alignment member> (size=4)
| | <alignment member> (size=4)
| +---
32 | c
| <alignment member> (size=4)
+---
+--- (virtual base A)
40 | a
+---

但对于 msvc 19.28 x86,结果将是:

class C size(24):
+---
0 | +--- (base class B1)
0 | | {vbptr}
4 | | b1
| +---
8 | +--- (base class B2)
8 | | {vbptr}
12 | | b2
| +---
16 | c
+---
+--- (virtual base A)
20 | a
+---

更新

需要注意的是,上面的类布局清楚地展示了虚拟继承的特征,其中只有一个基类实例(A)的拷贝被孙子派生类()继承C).如果 A::a 数据成员是公共(public)的,我们可以在类 C 的成员函数中使用以下语句:

void C::foo() {
B2::a = 1;
B1::a = 2;
std::cout << B2::a << " " << B1::a << " " << A::a; // Output: 2 2 2
}

但是如果你不使用虚继承(只是public),那么类C的布局会是这样的:

class C size(20):
+---
0 | +--- (base class B1)
0 | | +--- (base class A)
0 | | | a
| | +---
4 | | b1
| +---
8 | +--- (base class B2)
8 | | +--- (base class A)
8 | | | a
| | +---
12 | | b2
| +---
16 | c
+---

我们将有两个基类成员变量的拷贝 A

void C::foo() {
B2::a = 1;
B1::a = 2;
std::cout << B2::a << " " << B1::a; // Output: 1 2. `A::a` ambiguity error
}

关于c++ - 了解虚拟派生类的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65630855/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com