【问题标题】:C++ : How can I know the size of Base class SubObject?C++:如何知道基类 SubObject 的大小?
【发布时间】:2010-12-02 19:27:45
【问题描述】:
.
Here 我在讨论空基优化,MSalters 发表了这个有趣的评论:
任何课程都不可能有
sizeof(Class)==0,是否为空。 但是
我们正在专门讨论
空基类子对象的大小。
它不需要自己的 vtable,也不需要
虚表指针。假设共同
vtable 指针在偏移量处的布局
0;这将导致零大小
基类子对象共享其
带有派生类的 vtable 指针。
没问题:那些应该是相同的
无论如何,这就是重点
虚函数。
我的具体问题是:当我们使用 Empty Class 作为基类时,编译器可能会优化,也可能不会。我们如何确定它的实际作用?
一般来说,我们如何知道基类子对象的大小?无论我们是否将其用作基础,基础子对象的大小是否相同?编译器是否只使用空基类进行优化?
.
【问题讨论】:
标签:
c++
class
compiler-construction
abstract-class
compiler-optimization
【解决方案1】:
很好的答案。
顺便说一句,MS VC++ 和 G++ 编译器可以转储类布局供您学习。
使用 VC++ 只需运行 cl.exe /c /d1reportAllClassLayout <source>.cpp
这使用我在 1990 年编写的类和 vtable 布局转储代码来测试正确的布局对象、vtables、vbtables 等。
为了更好地了解 C++ 编译器如何在内存中布置对象,您可能会喜欢 http://www.openrce.org/articles/files/jangrayhood.pdf 和 Stan Lippman 的《深入 C++ 对象模型》一书。
黑客愉快!
【解决方案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>))
【解决方案3】:
你不能。实际大小可能与sizeof() 作为基准时的信息相差很大。
除 EBO 之外的另一个例子是虚拟继承。