对象的大小是否受访问说明符类型和继承类型影响? [英] Is size of the object affected by type of access-specifier and type of inheritance?
问题描述
在回答一个问题时,有一个讨论线程在我的答案下面。这表明取决于访问说明符(或可能是继承的类型) private / protected / public
sizeof
class
对象可能有所不同!
While answering one of the question, there was a discussion thread below my answer. Which suggests that depending on the access specifier (or may be the type of inheritance) private/protected/public
the sizeof
the class
object may vary!
从他们的简短讨论中我仍然不明白,这怎么可能?
I still don't understand from their brief discussion, how is that possible ?
推荐答案
请注意以下C ++ 11的新语言
在C ++ 03 中,有一种语言使之成为可能,即9.2 [class.mem] / 12(强调我的意思):
In C++03, there is language that makes this possible, 9.2 [class.mem]/12 (emphasis mine):
分配了声明为而没有中间访问说明的(非联盟)类的非静态数据成员,以便以后的成员在类对象中具有更高的地址。 由访问说明符分隔的非静态数据成员的分配顺序不确定(11.1)。实施一致性要求可能会导致两个相邻成员不能彼此立即分配;因此管理虚拟功能(10.3)和虚拟基类(10.1)的空间要求也可能如此。
Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).
因此,给出以下定义:
class Foo
{
char a; //8 bits
// a must come before b, so 3 bytes of padding have to go here to satisfy alignment
int b; //32 bits
char c; //8 bits
// 24 bits of padding required to make Foo a multiple of sizeof(int)
};
在具有32位( int
)对齐方式,不允许编译器重新排序 c
到 b
之前,从而在其中强制插入其他填充在 a
和 b
之间,并且在 c
之后对象的大小(使 sizeof(Foo)== 12
)。但是,为此:
on a system with 32 bit (int
) alignment, the compiler is not allowed to reorder c
to come before b
, forcing the insertion of additional padding padding in between a
and b
, and after c
to the end of the object (making sizeof(Foo) == 12
). However, for this:
class Foo
{
char a;
public:
int b;
public:
char c;
};
a
和( b
和 c
)由访问说明符分隔,因此编译器可以自由地执行这种重新排序,从而使
a
and (b
and c
) are separated by an access specifier, so the compiler is free to perform such reordering, making
memory-layout Foo
{
char a; // 8 bits
char c; // 8 bits
// 16 bits of padding
int b; // 32 bits
};
sizeof(Foo)== 8
。
在C ++ 11 中,语言略有变化。 N3485 9.2 [class.mem] / 13说(强调我的意思):
In C++11, the language changes slightly. N3485 9.2 [class.mem]/13 says (emphasis mine):
(非联盟)类的非静态数据成员具有相同的访问控制(第11条),以便以后的成员在类对象中具有更高的地址。 未指定具有不同访问控制的非静态数据成员的分配顺序(第11条)。实施一致性要求可能会导致两个相邻成员不能彼此立即分配;管理虚拟功能(10.3)和虚拟基类(10.1)的空间要求也可能如此。
Nonstatic data members of a (non-union) class with the same access control (Clause 11) are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified (Clause 11). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).
这意味着在C ++中参照图11,在上面的示例(由3个公众分隔)中,仍然不允许编译器执行重新排序。
This means that in C++11, in the above example (separated by 3 publics), the compiler is still not allowed to perform the reordering. It would have to be something like
class Foo
{
char a;
public:
int b;
protected:
char c;
};
,其中放置 a
, b
和 c
具有不同的访问控制。
, which places a
, b
, and c
with different access control.
请注意, C ++ 11规则,给出如下定义:
Note that under the C++11 rules, given a definition like:
class Foo
{
char a;
public:
int b;
protected:
char c;
public:
int d;
};
编译器必须在<$之后放置 d
c $ c> b ,即使它们被访问说明符隔开。
the compiler must put d
after b
, even though they are separated by access specifiers.
(那说,我不知道有任何实际利用任何一种标准提供的纬度的实现)
(That said, I'm not aware of any implementation that actually takes advantage of the latitude offered by either standard)
这篇关于对象的大小是否受访问说明符类型和继承类型影响?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!