编辑:我刚刚意识到提出这个问题的一种更简单的方法:
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
中有这段 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)的、私有(private)的还是 protected ?
编辑:为了使它更明显,Thing
的两个定义之间的唯一区别是 float b;
是私有(private)的在 fileA.cpp
中,但在 fileB.cpp
中公开。
最佳答案
标准没有做出这样的保证。您只有标准布局类的布局保证:
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,[类]¶7)
如果一个类是标准布局,则其布局定义良好(两个具有布局兼容初始序列的标准布局类可以通过 union
读取彼此的布局兼容成员)。
但是,这里不是这种情况,因为您在整个类中有不同的访问说明符。特别是,它明确指出
The order of allocation of non-static data members with different access control is unspecified
(C++14, [class.mem] ¶13)
话虽这么说,但我从未使用过任何利用标准提供的这种灵 active 的现实世界编译器 - 我知道的每个编译器都使用访问说明符进行编译时检查,但完全忽略它们就成员布局而言。
关于c++ - public/private/protected 是否会改变结构在内存中的排列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52744874/