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

问题描述 投票:0回答: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; }
};

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

但是,我怀疑由于 C++ 要求对象大小至少为 1 个字节,

Derived
的大小将变为 9 个字节,因此,由于填充/对齐,它将进一步变为 16 个字节。

那么C++中有没有办法让

Derived
的大小等于
double
的大小(通常是8字节)? 标准对
Derived
的尺寸有何规定? 特别是,MSVC++ 在这种情况下表现如何?

c++ generics inheritance sizeof empty-class
1个回答
7
投票

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

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 错误页面。看来他们根本不打算解决这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.