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



考虑以下继承:

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; }
};

此代码段将在模板化代码库中使用。多态性不是一个选项,因为它添加了 VTable 指针,从而使内存消耗加倍。

但是,我怀疑由于C++要求对象的大小至少为 1 个字节,Derived的大小将变为 9 个字节,因此,由于填充/对齐,它将进一步变为 16 个字节。

那么C++有没有办法保持Derived的大小等于double的大小(通常为 8 个字节)? 标准对Derived的大小有什么规定? 特别是,MSVC++ 在这种情况下的行为如何?

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

1.8 C++对象模型

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 连接错误页面。看起来他们毕竟不打算修复它。

最新更新