public/private/protected 会改变结构在内存中的排列吗?
Do public/private/protected change the arrangement of a struct in memory?
编辑: 我刚刚意识到提出这个问题的一种更简单的方法:
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?
老问题
假设我们在 fileA.cpp
:
中有这个 C++ 代码
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;
}
假设我们在 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;
}
假设编译器不会报错,这段代码会按预期工作吗?也就是说,结构数据的排列是否独立于某些组件是 public、私有的还是受保护的?
编辑: 为了更明显,Thing
的两个定义之间的唯一区别是 float b;
在 fileA.cpp
但 public 在 fileB.cpp
.
标准没有做出这样的保证。您只有标准布局的布局保证 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)
如果一个class是标准布局,它的布局是明确定义的(并且两个具有布局兼容初始序列的标准布局class可以通过读取彼此的布局兼容成员union
).
然而,这里不是这种情况,因为在 class 中您有不同的访问说明符。特别是,它明确指出
The order of allocation of non-static data members with different access control is unspecified
(C++14, [class.mem] ¶13)
话虽这么说,但我从未使用过任何利用标准提供的这种灵活性的现实世界编译器——我知道的每个编译器都使用访问说明符进行编译时检查, 但就成员布局而言完全忽略它们。
编辑: 我刚刚意识到提出这个问题的一种更简单的方法:
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
, andc
guaranteed to be in the same order in memory for both of these definitions?
老问题
假设我们在 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;
}
假设我们在 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;
}
假设编译器不会报错,这段代码会按预期工作吗?也就是说,结构数据的排列是否独立于某些组件是 public、私有的还是受保护的?
编辑: 为了更明显,Thing
的两个定义之间的唯一区别是 float b;
在 fileA.cpp
但 public 在 fileB.cpp
.
标准没有做出这样的保证。您只有标准布局的布局保证 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)
如果一个class是标准布局,它的布局是明确定义的(并且两个具有布局兼容初始序列的标准布局class可以通过读取彼此的布局兼容成员union
).
然而,这里不是这种情况,因为在 class 中您有不同的访问说明符。特别是,它明确指出
The order of allocation of non-static data members with different access control is unspecified
(C++14, [class.mem] ¶13)
话虽这么说,但我从未使用过任何利用标准提供的这种灵活性的现实世界编译器——我知道的每个编译器都使用访问说明符进行编译时检查, 但就成员布局而言完全忽略它们。