c++ - C ++多重继承增加了类的大小?
问题描述
好吧,我在 C++、MSVC 编译器中遇到了一个奇怪的行为。
如果你写
struct Class1 {};
struct Class2 : Class1 {};
struct Class3 : Class2 {};
struct Class4 : Class3 {};
asizeof(Class4)
将返回 1,a 预期。但是如果你写
struct Class1 {};
struct Class2 {};
struct Class3 {};
struct Class4 : Class1, Class2, Class3 {};
在sizeof(Class4)
运行时将是两个。IntelliSenseconstexpr auto x = sizeof(Class4)
并将指示值 1,但我遇到了一些模板技巧,它报告大于 1 的值,它们甚至与实际运行时值不匹配。
阅读论坛我发现了这个:
如果您从一个空类继承,但编译器的 ABI 不允许该类与该类的其他部分重叠其布局,则该类的大小也会由于纯填充而增加。考虑将 C++20(即将推出)属性 [[no_unique_address]] 作为替代方案。
我知道,但我仍然觉得奇怪的是行为会根据我使用的继承实现而改变。对这个问题有什么想法吗?
编辑:
对于最小的可重现示例:
// "Sequential" inheritance
struct S0 {};
struct S1 : S0 {};
struct S2 : S1 {};
struct S3 : S2 {
int val;
int foo() { return val; }
};
// "End" inheritance
struct E0 {};
struct E1 {};
struct E2 {};
struct E3 : E0, E1, E2 {
int val;
int foo() { return val; }
};
int main() {
S3 s = S3();
E3 e = E3();
std::cout << sizeof(s) << "\n" << sizeof(e) << "\n" << (sizeof(s) == sizeof(e));
return 0;
}
哪个打印出来
4
8
0
所以类 S3 的实例有sizeof
4,但 E3 的实例有sizeof
8。最终的问题是为什么。为什么这两个类,S3 和 E3,根据继承的方式有不同的大小?
编辑2:
差点忘了,我所说的运行时和编译时是什么意思,虽然程序执行返回了这些值,但如果您在之前添加的代码下方
constexpr auto sizS3 = sizeof(S3); // IntelliSense report 4, prints 4
constexpr auto sizE3 = sizeof(E3); // IntelliSense report 4, prints 8
constexpr auto equal = sizS3 == sizE3; // IntelliSense report true, prints false (0)
IntelliSense 将报告这两个值都是 4U,但打印这些值与打印实例S3 s
和E3 e
.
解决方案:
所以,在研究了更多之后,发现了这个问题:为什么空基类优化(EBO)在 MSVC 中不起作用?
struct __declspec(empty_bases) E3 : E0, E1, E2 {
int val;
int foo() { return val; }
};
将按预期工作。
解决方案
推荐阅读
- python - 如何构建 Windows 机器人(在 Windows 上控制 UI 应用程序)
- javascript - 如何取消 redux-saga 中正在运行的网络请求?
- java - 我收到错误 java.text.ParseException: Unparseable date null
- sms - Messagebird SMS webhook - 令人困惑?
- php - 无法使用 PHP API v4 在 Google 表格中追加行
- php - 输入'列表
' 不是类型 'Map 的子类型 - python - 在 pandas 中查找列的所有可能成对组合,并将它们各自的单元格相乘在另一列中
- pandas - 了解应用 lambda Pandas
- javascript - Javascript ES6 仅从文件夹中导入一些文件
- javascript - 在反应中同时访问两个状态