简体   繁体   中英

How memory is allocated for private and public members of the class

In a class, are private members allocated in separate memory from public members, or all members allocated in the sequence of their definition?

For example,

class A { 

private:  
    int a1;
    int a2:3;  
public:  
    int z;  
    int a3:2;  
    int a4:5;  
private:
    int a5:2;
}

Are a1 , a2 , and a5 clubbed together for memory allocation or is it simply a1 , a2 , a3 , a4 , a5 ?

If clubbing happens it might change the size of the class in case of bit fields.

  • Within a given accessibility block, the order of members is preserved, but between accessibility blocks member order is unspecified in C++03. This means that a1, a2, a5, z, a3, a4 would be a valid order in your example above.
  • In C++11 this is strengthened such that members with the same accessibility must be placed in declared order. (eg this bans a5 a1 a2 f a3 a4 in your example because a5 is declared after a1 and a2 in your example) Order between members with different accessibility is unspecified.
  • The compiler may insert padding between any member (eg in order to maintain alignment)
  • The representation of bit fields is unspecified. They may be placed in any order and do not respect any of the previous rules. Because you cannot take the address of a bit field, there is no mechanism to observe this.

Specific standard references (emphasis mine):

C++03 9.2 [class.mem]/12:

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).

N3376 (the first post C++11 draft) 9.2 [class.mem]/13:

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. 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).

N3376 9.6 [class.bit]/1:

[...] Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. [...]

/3:

[...] The address-of operator & shall not be applied to a bit-field, so there are no pointers to bitfields. [...]

C++ answer:

I may miss something and if I do please post a comment.

In C++ Objects are laid on based on the type of class. In the standard, I believe only a few types of classes guarantee ordering of members.

POD or Plain Old Data classes/structs are laid out exactly as they appear. With each member following the ones declared above with added padding. POD classes/structs are ones that do not contain any access modifiers, do not have any user defined constructor/desctructor. Has no statically declared members, and contains only POD member types.

Ex:

struct POD {
    int x;
    int y;
    int z;
};

Most other types of classes do not define how members are laid out in memory. A compiler is free to place members how it sees fit if a class/struct has multiple access modifiers. Again C++ should be similar to Java in that you shouldn't really care much about how it is laid out for most cases that do not involve working with hardware.

The following was added before the java tag was removed, but remains for future reference.

Java answer:

Java makes no guarantee on how an object is laid out in memory, and you shouldn't care. The JVM is free to layout an object how ever it likes in memory. This means that Objects don't have to even be in consecutive memory.

Now this isn't done in any JVMs that I am aware of. A much better guess would be that it lays out Objects similar to how they are done in C++. Where each parent class members are placed before the child members, and that each member within a class is laid out consecutively based on size with the needed padding.

If you want to inspect how a particular Object is laid out in memory you could use reflection along with the sun.misc.Unsafe class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM