简体   繁体   中英

Do public/private/protected change the arrangement of a struct in memory?

Edit: I just realized a much simpler way to ask this question:

Given the following two structs:

 class Thing {public: int a; public: int b; public: int c;} class Thing {public: int a, private: int b; public: int c;} 

Are the members a , b , and c guaranteed to be in the same order in memory for both of these definitions?


Old Question

Let's say we have this C++ code in fileA.cpp :

class Thing
{
public:
    int a;
    double num;

    Thing()
    {
        b = 10;
    }

    float getB()
    {
        return b;
    }

private:
    float b;
    Thing * other;
}

void doSomething(Thing thing);

int main()
{
    Thing thing;
    doSomething(thing);
    std::cout << thing.b;
}

And let's say we have this code in fileB.cpp :

class Thing
{
public:
    int a;
    double num;

    Thing()
    {
        b = 10;
    }

    float getB()
    {
        return b;
    }

    float b;

private:
    Thing * other;
}

void doSomething(Thing thing)
{
    thing.b = 30;
}

Assuming the compiler wouldn't complain, would this code work as expected? That being, is the arrangement of a struct's data independent of whether or not certain components are public, private, or protected?

Edit: To make it more obvious, the only difference between the two definitions of Thing is the fact that float b; is private in fileA.cpp but public in fileB.cpp .

The standard makes no such guarantee. You have layout guarantees only for standard-layout classes:

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.

(C++14, [class] ¶7)

If a class is standard-layout, its layout is well defined (and two standard layout classes that have a layout-compatible initial sequence may read each other's layout-compatible members through a union ).

However, here it is not the case, as you have different access specifiers throughout the class. In particular, it's explicitly stated that

The order of allocation of non-static data members with different access control is unspecified

(C++14, [class.mem] ¶13)


That being said , I never worked with any real world compiler that ever exploited this flexibility offered by the standard - every compiler I know uses the access specifiers for compile-time checks, but ignores them completely as far as members layout is concerned.

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