公共和私有对对象的内存布局有影响吗?

Fab*_*ian 27 c++

这是我的另一个问题的后续问题:班级成员的最佳顺序是什么?

如果我以公共,受保护和私人轮流的方式组织成员,它是否会改变任何事物(可见性除外)?

class Example
{
public:
  SomeClass m_sc; 
protected:
  char m_ac[32];      
  SomeClass * m_scp;
private:
  char * m_name;
public:
  int m_i1;
  int m_i2;
  bool m_b1;
  bool m_b2;
private:
  bool m_b3;
};
Run Code Online (Sandbox Code Playgroud)

这个类和我在运行时公开所有成员的类之间有区别吗?我想遵循从大到小排序类型的规则(如果可读性没有受到严重损害).

我认为它根本不会影响编译的程序,就像const只在编译期间检查一样.它是否正确?

Rei*_*ica 34

答案取决于语言版本,因为这已从C++ 03更改为C++ 11.

在C++ 03中,规则是:

相同的访问控制块内的成员(即,由一种public,protected,private关键字,从该组中的下一个)是类中声明的顺序进行分配,而不是一定是连续的.

在C++ 11中,规则已更改为:

具有相同访问控制级别(公共,受保护,私有)的成员将按照类中的声明顺序进行分配,而不一定是连续的.

所以在C++ 03中,你可以保证这一点(我@用来表示类中成员的偏移量):

  • @m_ac < @m_scp
  • @m_i1 < @m_i2 < @m_b1 < @m_b2

在C++ 11中,您还有一些保证:

  • @m_ac < @m_scp
  • @m_sc < @m_i1 < @m_i2 < @m_b1 < @m_b2
  • @m_name < @m_b3

在这两个版本中,编译器可以根据需要对不同链中的成员进行重新排序,甚至可以对链进行交错.


请注意,还有一种机制可以进入图片:标准布局类.

如果类没有虚拟,如果所有非静态数据成员具有相同的访问控制,则它是标准布局,它没有基类或非标准布局类型或引用类型的非静态数据成员,如果它最多只有一个类,其继承链中包含任何非静态数据成员(即它既不能定义自己的非静态数据成员,也不能从基类继承一些非静态数据成员).

如果一个类是标准布局,那么还可以保证其第一个非静态数据成员的地址与类对象本身的地址相同(这意味着在类布局的开头不能出现填充) .

请注意,标准布局的条件以及不做出悲观选择的实际编译器实际上意味着在标准布局类中,成员将按照声明的顺序连续排列(根据需要填充用于对齐的填充).

  • @JanDvorak 不,抱歉。我不会对数据成员排序如此重要的系统进行编程,所以我从来没有理由去查找它。我想说,平台 ABI 文档和编译器文档可能是寻找答案的良好起点。 (2认同)