.
这里我正在讨论空基优化,MSalters做了这个有趣的评论:
没有一个班级可以有 sizeof(Class)==0,是否为空。 但是 我们正在具体讨论 空基类子对象的大小。 它不需要自己的 vtable,也不需要 虚函数表指针。假设常见的 虚函数表指针在偏移处的布局 0;这会导致零大小 基类子对象共享其 带有派生类的 vtable 指针。 没问题:这些应该是相同的 无论如何,这就是重点 虚函数。
我的问题具体是这样的:当我们使用空类作为基类时,编译器可能会优化,也可能不会。我们如何确定它的实际作用?
一般来说,我们如何知道基类子对象的大小?无论我们是否使用 Base 子对象作为基础,它的大小是否相同?编译器仅针对空基类进行优化吗?
.
很好的答案。
顺便说一句,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。
黑客快乐!
物体的最小尺寸为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>))
你不能。作为基础时,实际尺寸可能与
sizeof()
信息有很大差异。
EBO 之外的另一个例子是虚拟继承。