Here我在讨论空基优化,MSalters发表了这个有趣的评论:
没有班级可以拥有 sizeof(Class)== 0,空或不。的但 我们专门谈论 空基类子对象的大小。 它不需要自己的vtable,也不需要 vtable指针。假设共同点 偏移处的vtable指针的布局 0;这将导致零大小 基类子对象分享它 vtable指针与派生类。 没问题:那些应该是相同的 无论如何,这就是重点 虚函数。
我的问题具体是这样的:当我们使用Empty Class作为基类时,编译器可能会优化,或者它可能不会。我们如何确定它实际上做了什么?
一般来说,我们如何知道基类子对象的大小? Base子对象的大小是否相同,无论我们是否使用它作为基础?编译器是否仅使用空基类进行优化?
答案 0 :(得分:4)
好的答案。
顺便说一句,MS VC ++和G ++编译器可以转储类布局供你学习。
使用VC ++运行cl.exe /c /d1reportAllClassLayout <source>.cpp
这使用我在1990年写的类和vtable布局转储代码来测试正确的布局对象,vtable,vbtables等。
为了更好地理解C ++编译器如何在内存中布置对象,您可能会喜欢http://www.openrce.org/articles/files/jangrayhood.pdf和Stan Lippman的书“Inside the C ++ Object Model”。
快乐的黑客攻击!
答案 1 :(得分: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>))
答案 2 :(得分:0)
你做不到。作为基础时,实际大小可能与sizeof()
信息有很大不同。
除EBO之外的另一个例子是虚拟继承。