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

C++ 派生C+的大小是多少+;如果基类没有成员,是否初始化?,c++,generics,inheritance,size,sizeof,C++,Generics,Inheritance,Size,Sizeof,考虑以下继承: 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; } }; 此代码段将在模板化的代码库中

考虑以下继承:

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字节的大小,所以<>代码>派生/代码>的大小将变成9字节,因此,由于填充/对齐,它将进一步变成16字节。

< C++ >有没有一种方法来保持<代码>派生的< /代码>等于代码的大小?双< /代码>(通常为8字节)? 标准对
派生的
的大小有何规定?
特别是,MSVC++在这种情况下是如何工作的?

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

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

七, 除非是位字段(9.2.4),最派生的对象应具有非零大小,并应占用一个或多个字节的存储空间。基类子对象的大小可以为零。普通可复制或标准布局类型(3.9)的对象应占用连续的存储字节

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

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

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; }
};
classbase1
{};
模板classbase2:公共TBase
{};
模板classbase3:公共TBase
{};
派生类:public Base3>
{};

。看起来他们根本没有打算修复它。

@AndyG,我不想
打包(1)
,因为尽管我会通过使
派生的
长9个字节来节省内存,但如果对
双倍的
值进行未对齐访问,我将受到巨大的惩罚,并且我将失去有效使用AVX2的可能性。或者,你可以用C++11(我忘了这一点的额头拍打)强制它,你可以在MSVC中检查自己。Try
constexpr auto test=sizeof(派生)。Intellisense应该能够为您提供
test
的值,您甚至不需要编译。它可能已经是8个字节了-但是请检查-这是由于空基类优化。查一查。