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

C++ C++;:如何知道基类子对象的大小?,c++,class,compiler-construction,abstract-class,compiler-optimization,C++,Class,Compiler Construction,Abstract Class,Compiler Optimization,我正在讨论空基优化,并发表了以下有趣的评论: 任何班级都不可能有 sizeof(Class)==0,是否为空但是 我们正在讨论具体的问题 空基类子对象的大小。 它不需要自己的vtable,也不需要 可变指针。承担共同责任 偏移处vtable指针的布局 0; 这将导致零尺寸 要共享其子对象的基类子对象 具有派生类的vtable指针。 没问题:它们应该是相同的 不管怎么说,这就是重点 虚拟函数的定义 我的问题是:当我们使用空类作为基类时,编译器可能会优化,也可能不会。我们如何确定它的实际用途 一般来

我正在讨论空基优化,并发表了以下有趣的评论:

任何班级都不可能有 sizeof(Class)==0,是否为空但是 我们正在讨论具体的问题 空基类子对象的大小。 它不需要自己的vtable,也不需要 可变指针。承担共同责任 偏移处vtable指针的布局 0; 这将导致零尺寸 要共享其子对象的基类子对象 具有派生类的vtable指针。 没问题:它们应该是相同的 不管怎么说,这就是重点 虚拟函数的定义

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

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


.

你不能。当用作基准时,实际大小可能与
sizeof()
信息有很大不同


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

对象的最小大小为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";
}
总结:

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>))
size\u of_type(X)=size\u of_type(base)+和(size\u of_type(members))+填充+(额外的东西,如vtable指针等);
sizeof()=最小值(1,大小为类型()的大小)
答案不错

顺便说一下,MS VC++和G++编译器可以转储类布局供您学习

使用VC++只需运行
cl.exe/c/d1reportAllClassLayout.cpp

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

<> >为了更好地理解C++编译器如何在内存中部署对象,您可能喜欢C++的对象模型中的Stan Lippman的书。 快乐的黑客

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>))