【问题标题】: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 之外的另一个例子是虚拟继承。

        【讨论】:

          猜你喜欢
          • 2017-07-06
          • 2016-01-03
          • 2014-03-01
          • 2015-01-15
          • 2010-12-31
          • 2013-12-23
          • 2015-08-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多