如果基类没有成员,派生C ++类的大小是多少?

时间:2017-05-25 18:50:29

标签: c++ generics inheritance size sizeof

考虑以下继承:

<div *ngSwitchCase="'Animals'">
      <div *ngFor="let item of result.details">
        <canvas [datasets]= "item.gender" [labels]="item.location" [chartType]="horizontalBar"></canvas>
      </div>
    </div>

此代码段将用于模板化代码库。多态性不是一种选择,因为它增加了VTable指针,从而使内存消耗增加了一倍。

但是,我怀疑由于C ++要求对象的大小至少为1个字节,因此class Base { protected: Base() { } public: double Multiply(double x); }; class Derived : public Base { double _value; public: Derived(double init) : _value(init) { } double Multiply(double x) { return x*_value; } }; 的大小将变为9个字节,因此,由于填充/对齐,它将进一步变为16个字节。

在C ++中是否有一种方法可以使Derived的大小等于Derived的大小(通常是8个字节)? 标准对double的大小有何评价? 特别是,在这种情况下,MSVC ++如何表现?

1 个答案:

答案 0 :(得分:6)

这称为空基优化,它在标准中定义如下:

  

1.8 C ++对象模型[intro.object]

     

7   除非它是位字段(9.2.4),否则大多数派生对象应具有非零大小并且应占用一个或多个存储字节。基类子对象可以具有零大小。平凡可复制或标准布局类型(3.9)的对象应占用连续的存储字节。

     

8   除非对象是零字段或零大小的基类子对象,否则该对象的地址是地址   它占据的第一个字节。两个对象a和b具有重叠的生命周期,而不是位字段可能具有   如果一个嵌套在另一个中,或者如果至少有一个是零大小的基类子对象,则为相同的地址   它们有不同的类型;否则,他们有不同的地址。

在您的示例中,继承Base类不会影响Derived类的大小。但是,MSVC ++仅对第一个空基类执行此类优化,因此从添加的空基类继承将导致Derived类大小的增长。我相信这已成为MSVC ++长期以来的批评点,因为许多其他编译器都没有这个问题。如果你有很多小辅助类,这可能真的很麻烦。作为一种变通方法,可以使用派生模板基类将多重继承转换为单继承链:

class Base1
{};

template< typename TBase > class Base2: public TBase
{};

template< typename TBase > class Base3: public TBase
{};

class Derived: public Base3< Base2< Base1 > >
{};

MS Connect bug page。看起来他们似乎并不打算修复它。