爱技术 & 爱分享
爱蛋蛋 & 爱生活

Data Member 布局

在class 中,nonstatic data member 在 class object 中的排列顺序和其被声明的顺序一样。

static data member 会存放在程序的data segment中,和class object 无关。

C++ Standard要求,在同一个 access section(private,public,protect)中,member的排列只需要符合“较晚出现的 member 在 class object 中有较高的地址”。

也就是说,各个members 并不一定要连续排列,所以class中也允许因字节对齐(alignment)而填补的bytes。这对于现代C++和编译器都是真的。

编译器还可能会合成一些内部使用的 data members,以运转整个对象模型,比如vptr,目前所有的编译器都把它安插在每一个具有virtual function的class 的object内。

那么这个插入的vptr 会被放置在什么位置呢?现在的很多编译器都把 vptr放在object的首部(比如 Visual C++),以前也有很多编译器将其放在所有显式声明的 members之后。

不过对于如何放置,C++ Standard 是交给了厂商自己来实现的,所有我们在网上看到的很多关于类的内存布局的文章,里面很多关于vptr放置位置介绍时,需要着重看一下 他是在什么编译器下验证的。理论上来说,如果厂商开心,他可以把 vptr放在object的任何地方,不过据我所知,如今基本上都是放在首部的。

C++ Standard 也允许 编译器将多个 access section之中的 data member 自由排列,而不在乎他们在 class 声明中的顺序。 不过经过测试,在Visual studio 2017 和 GCC7.2中编译器都没有调整他们的声明顺序(无论是否是同一个 access section)。

所以这个类的size 会是16而不是12

class test
{
public:
    int i;
private:
    char q;
public:
    int j;
private:
    char w;
    char e;
    char r;
};

意思是 同为private的member 并没有没移动到一起。不过也有可能有些编译器会重新排列 member的顺序。

赞(0) 传送门
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。墨影 » Data Member 布局