12

I come from C programming where the data in a struct is laid out with the top variable first, then the second, third and so on..

I am now programming in C++ and I am using a class instead. I basically want to achieve the same, but I also want get/set methods and also maybe other methods (I also want to try do it in a C++ style and maye learn something new).

Is there a guarantee e.g. that the public variables will be first in memory then the private variable?

Columbo
  • 60,038
  • 8
  • 155
  • 203
uniquenamehere
  • 1,869
  • 3
  • 31
  • 60
  • 1
    The only difference is access rights. Rule of thumb keep hot variables at the top. – 101010 Nov 14 '14 at 22:06
  • 8
    There's absolutely no difference in layout between a class and a struct. – Mark Ransom Nov 14 '14 at 22:06
  • So if I define the public variables first they will be first in memory? And I assume that I can actually get access to the private members this way? – uniquenamehere Nov 14 '14 at 22:07
  • Why do you need to know how the data is laid out in memory? I know it's nice to understand, but in many cases in practice, if you need to know, that may be an indication you're doing something wrong... – psmears Nov 14 '14 at 22:20
  • I have a byte array with data that is received and I want to be able to cast to a type of this class. This way all data fields will be set in one line. EDIT: This might not work if the functions take memory... I guess a struct is what I need =/ – uniquenamehere Nov 14 '14 at 22:22
  • 1
    That should be possible if the class is "simple" (probably meeting the standard-layout-class criteria Columbo mentioned) and the array is a char array (not an int array or such). You are basically performing binary (de)serialization which is not uncommon. – Peter - Reinstate Monica Nov 17 '14 at 08:47

2 Answers2

18

Is there a guarantee e.g. that the public variables will be first in memory then the private variable?

No, such a guarantee is not made - C++11 standard, [class.mem]/14:

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

So

struct A
{
    int i, j;
    std::string str;

private:

    float f;

protected:

    double d;
};

It is only guaranteed that, for a given object of type A,

  • i has a smaller address than j and
  • j has a smaller address than str

Note that the class-keys struct and class have no difference regarding layout whatsoever: Their only difference are access-rights which only exist at compile-time.


It only says the order, but not that the first variable actually start at the "first address"? Lets assume a class without inheritance.

Yes, but only for standard-layout classes. There is a row of requirements a class must satisfy to be a standard-layout class, one of them being that all members have the same access-control.
Quoting C++14 (the same applies for C++11, but the wording is more indirect), [class.mem]/19:

If a standard-layout class object has any non-static data members, its address is the same as the address of its first non-static data member. Otherwise, its address is the same as the address of its first base classsubobject (if any). [ Note: There might therefore be unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment. — end note ]

[class]/7:

A standard-layout class is a class that:

  • has no non-static data members of type non-standard-layout class (or array of such types) or reference,
  • has no virtual functions (10.3) and no virtual base classes (10.1),
  • has the same access control (Clause 11) for all non-static data members,
  • has no non-standard-layout base classes,
  • either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
  • has no base classes of the same type as the first non-static data member. 110

110) This ensures that two subobjects that have the same class type and that belong to the same most derived object are not allocated at the same address (5.10).

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • So I can not assume they are in sequential order if I have both public and private variables? What if I have only public or only private? – uniquenamehere Nov 14 '14 at 22:11
  • 1
    Then they have indeed increasing addresses. As the quote says. – Columbo Nov 14 '14 at 22:11
  • It only says the order, but not that the first variable actually start at the "first address"? Lets assume a class without inheritance. – uniquenamehere Nov 14 '14 at 22:15
  • 1
    @Phataas Also added the requirement list. – Columbo Nov 14 '14 at 22:29
  • This gave me good insight and was very well explained! I was thinking of using the class to be able to cast to this class from a pointer to the start of an array, but I am now not sure if this is possible because of the accessor member functions and other possible padding etc in the class taking memory? – uniquenamehere Nov 14 '14 at 22:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/64972/discussion-between-columbo-and-phataas). – Columbo Nov 14 '14 at 22:32
5

First thing first: class and struct in C++ are very much the same - the only difference is that all members before the first access specifier in a class are considered private, while in a struct they are public.

Is there a guarantee e.g. that the public variables will be first in memory then the private variable?

There is no such guarantee. When there is no inheritance, the memory will be allocated to class members in the order in which you declare them within the same access group. It is up to the compiler to decide if the public member variables should be placed ahead of the private / protected ones or vice versa. Like C, C++ can add padding in between class members.

Inheritance makes things more complicated, because data members of the base class need to be placed within the derived class as well. On top of that, there is virtual inheritance and multiple inheritance, with complex rules.

I basically want to achieve the same [layout], but I also want get/set methods and also maybe other methods.

If you make all data members of your class private, and add accessor member functions (that's what C++ calls "methods" from other languages) you would achieve this effect.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523