为什么我添加了一个成员,但sizeof(BaseClass)== sizeof(DerivedClass) [英] Why is sizeof(BaseClass) == sizeof(DerivedClass) although I add a member
问题描述
从下面的代码中 sizeof(Base)== 24
和 sizeof(Derived)== 24
.
为什么它们的大小相等?
Why are their sizes equal?
在 Base
类中,我们有3个成员,在 Derived
类中,我们有另一个成员.
In Base
class we have 3 members and in Derived
class we have another member.
class Base
{
private:
double d;
protected:
long l;
public:
int i;
};
class Derived : public Base
{
private:
float f;
};
推荐答案
碰巧您的类 Base
具有8字节对齐要求,但其最后一个成员的大小为4.在 Base
的内存布局末尾添加了空白填充区域.当您自己实例化 Base
类的对象(即所谓的 most-derived objects )时,这种额外的填充发挥了作用.
It just so happened that your class Base
has 8 byte alignment requirement, but its last member has size 4. This leads to an empty padding area added at the end of Base
's memory layout. That extra padding plays its role when you instantiate objects of class Base
by themselves, as so called most-derived objects.
Base b; // <- a most-derived object
Base a[10]; // <- an array of most-derived objects
但是,当您将 Base
作为基类嵌入"到 Derived
类中时,则不需要在嵌入式 Base
子对象.
However, when you "embed" Base
as base class into class Derived
, there's no need for that extra padding at the end of the embedded Base
subobject.
Derived d; // <- object `d` contains an embedded sub-object of type `Base`
一个聪明的编译器会通过将类 Derived
的额外字段放入用于在 Base
中进行填充的布局区域中来尝试重用该区域.在您的情况下,额外字段 Derived :: f
的大小为4个字节,即恰好适合该字段.最终结果是该班级的总人数没有增加.
A smart compiler will attempt to reuse that area by placing the extra field of class Derived
into the layout area used for padding in Base
. In your case the extra field Derived::f
incidentally has the same size of 4 bytes, i.e. it fits in there perfectly. The end result is that the total size of the class does not increase.
一个非常相似的(本质上)效果被称为空基优化".在C ++中,确保任何类型的 sizeof
都大于0,这意味着空类的 sizeof
始终大于零.但是,当您从一个空的基类派生其他类时,您可能会发现基类为派生类的大小贡献了0个字节.例如
A very similar (in nature) effect is so called "empty base optimization". In C++ sizeof
for any type is guaranteed to be greater than 0, which means that sizeof
of an empty class is always greater than zero. However, when you derive some other class from an empty base class, you might observe that the base class contributes exactly 0 bytes to the derived class's size. For example
struct A {};
struct B {};
struct C {};
struct D {};
struct F : A, B, C, D {
int i;
}
int main() {
std::cout << sizeof(A) << std::endl << sizeof(B) << std::endl <<
sizeof(C) << std::endl << sizeof(D) << std::endl;
std::cout << sizeof(F) << std::endl;
}
即使每个基类的 sizeof
大于零, sizeof(F)
通常仍将评估为 sizeof(int)
,好像根本没有子类.
Even though sizeof
of each base class is greater than zero, sizeof(F)
will typically still evaluate to sizeof(int)
, as if base class subobjects do not exist at all.
换句话说,如此类例所示,与大多数派生对象相比,基类子对象在内存布局方面遵循明显更宽松的规则.这些宽松的规则很容易导致基类的 sizeof
仅部分地有助于派生类的 sizeof
的情况.
In other words, as such examples show, base class subobjects follow noticeably more relaxed rules with regard to their memory layout than most-derived objects. These relaxed rules might easily lead to situations when sizeof
of base class will only partially contribute to sizeof
of derived class.
这篇关于为什么我添加了一个成员,但sizeof(BaseClass)== sizeof(DerivedClass)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!