问题
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 ?
回答1:
Note new language for C++11 below
In C++03, there is language that makes this possible, 9.2 [class.mem]/12 (emphasis mine):
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).
So given this definition:
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)
};
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
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
.
In C++11, the language changes slightly. N3485 9.2 [class.mem]/13 says (emphasis mine):
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).
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;
};
, which places a
, b
, and c
with different access control.
Note that under the C++11 rules, given a definition like:
class Foo
{
char a;
public:
int b;
protected:
char c;
public:
int d;
};
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)
来源:https://stackoverflow.com/questions/6577906/is-size-of-the-object-affected-by-type-of-access-specifier-and-type-of-inheritan