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中检查自己。Tryconstexpr auto test=sizeof(派生)代码>。Intellisense应该能够为您提供test
的值,您甚至不需要编译。它可能已经是8个字节了-但是请检查-这是由于空基类优化。查一查。