C++:我如何知道基类子对象的大小?

问题描述 投票:0回答:3

.

这里我正在讨论空基优化,MSalters做了这个有趣的评论:

没有一个班级可以有 sizeof(Class)==0,是否为空。 但是 我们正在具体讨论 空基类子对象的大小。 它不需要自己的 vtable,也不需要 虚函数表指针。假设常见的 虚函数表指针在偏移处的布局 0;这会导致零大小 基类子对象共享其 带有派生类的 vtable 指针。 没问题:这些应该是相同的 无论如何,这就是重点 虚函数。

我的问题具体是这样的:当我们使用空类作为基类时,编译器可能会优化,也可能不会。我们如何确定它的实际作用?

一般来说,我们如何知道基类子对象的大小?无论我们是否使用 Base 子对象作为基础,它的大小是否相同?编译器仅针对空基类进行优化吗?

.

c++ class abstract-class compiler-optimization
3个回答
4
投票

很好的答案。

顺便说一句,MS VC++ 和 G++ 编译器可以转储类布局供您研究。

使用 VC++ 只需运行

cl.exe /c /d1reportAllClassLayout <source>.cpp

这使用我在 1990 年编写的类和 vtable 布局转储代码来测试正确的布局对象、vtable、vbtable 等。

为了更好地了解 C++ 编译器如何在内存中布局对象,您可能会喜欢 http://www.openrce.org/articles/files/jangrayhood.pdf 和 Stan Lippman 的书 Inside the C++ Object Model。

黑客快乐!


2
投票

物体的最小尺寸为1:

class X {};
sizeof(X) >= 1

但是派生类如果不使用这个空间则不需要为其分配空间:

class Y : public X {};
sizeof(Y) >= 1

因此,即使类 X 本身占用 1 个字节,这也不会转换为父类。所以从 Y 的角度来看,类 X 占用 0 字节。

所以在这里我们可以说编译器已经优化了基类(尽管从技术上讲它没有做任何事情。我们只需要强制执行没有对象的大小为零的规则)。

int main()
{
    std::cout << sizeof(X) << ":" << sizeof(Y) << "\n";
}

生成以下输出:

> ./a.exe
1:1
>

类的大小必须大于零的原因是每个对象的地址都是唯一的。如果编译器允许类的大小为零,则存在一个潜在的简单错误,即多个变量(对象)都具有相同的内存地址(因为它们的大小都为零)。解决这个潜在问题的简单规则是所有对象都必须具有非零大小。

总结:

size_of_type(X) = size_of_type(base) + sum(size_of_type(members)) + padding + (extra stuff like vtable pointer etc);


sizeof(<CLASS>) = min(1, size_of_type(<CLASS>))

0
投票

你不能。作为基础时,实际尺寸可能与

sizeof()
信息有很大差异。

EBO 之外的另一个例子是虚拟继承。

© www.soinside.com 2019 - 2024. All rights reserved.