公共/私有/受保护是否会更改内存中结构的排列?



编辑:我刚刚意识到一个更简单的方法来问这个问题:

给定以下两个结构:

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

对于这两个定义,成员abc是否保证在内存中的顺序相同?


老问题

假设我们在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;
}

假设编译器不会抱怨,那么这段代码会按预期工作吗?也就是说,结构数据的排列是否独立于某些组件是公共的、私有的还是受保护的?

编辑:为了使它更明显,Thing的两个定义之间的唯一区别是float b;fileA.cpp是私有的,但在fileB.cpp是公开的。

标准没有这样的保证。您仅对标准布局类具有布局保证:

标准布局类是具有以下特性的类:

  • 没有非标准布局类(或此类类型的数组(类型的非静态数据成员或引用,
  • 没有虚函数(10.3(也没有虚拟基类(10.1(,
  • 对所有非静态数据成员具有相同的访问控制(条款 11(,
  • 没有非标准布局基类,
  • 要么在派生最多的类中没有非静态数据成员,并且最多有一个基类 非静态数据成员,或者没有具有非静态数据成员的基类,以及
  • 没有与第一个非静态数据成员类型相同的基类。

(C++14, [类] ¶7(

如果类是标准布局的,则其布局定义良好(并且具有布局兼容初始序列的两个标准布局类可以通过union读取彼此的布局兼容成员(。

但是,这里的情况并非如此,因为在整个类中有不同的访问说明符。特别是,它明确指出

未指定具有不同访问控制的非静态数据成员的分配顺序

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


话虽如此,我从未使用过任何利用标准提供的这种灵活性的真实编译器 - 我认识的每个编译器都使用访问说明符进行编译时检查,但就成员布局而言完全忽略了它们。

最新更新