C++对象中数据成员的布局

首先,对于类中定义的变量,各个编译器内部并没有强制规定成员布局的情况。

只有一些简单的标准:

1    在同一个访问控制标号(public,private,protected)中定义的非static变量在对象的内存布局顺序是按照定义的顺序

2    不同的访问控制标号下的(非static)成员变量并无先后顺序的要求。

3    编译器可能还会合成一些内部使用的数据成员,比如虚函数表的指针vptr;C++标准并没有规定那些内部产生的指针的位置

在内存中的位置,甚至可以放在其他成员变量之间。


比如如下的类定义:

class Point3d
{
private : int x;
private: int y;
private : int z;
};


在内存布局上x、y、z的布局并没有限制。


class Point3d
{
privtate:
int x,y,z;
};


//在内存布局中x、y、z是按定义顺序依次排列的。


对于上述的编译器内部产生的数据,如vptr,虽然并没有要求其具体存放位置,但是一般的编译器会将其放在对象内存的最开头或者是最后。

如下面的代码(下面的代码可以看出vptr被安放在最开头的位置)。

#include <iostream>
#include <cstdio>


using namespace std;


class Point3d
{
public:
    virtual ~Point3d(){}
public:
    static Point3d origin;
    float x,y,z;


};
int main()
{
    cout << sizeof(Point3d) << endl;
    printf("&Point3d::x : %p\n" ,&Point3d::x);
    printf("&Point3d::y : %p\n" ,&Point3d::y);
    printf("&Point3d::z : %p\n" ,&Point3d::z);


}


由于析构函数为虚函数,导致在该类的任何对象中都会生成一个vprt指针,结果显示:

C++对象中数据成员的布局_第1张图片

结果显示的是在对象内存布局中的成员变量的偏移量,依次为4,8,12,也就是说第一个位置是vptr;偏移量为0。这也正好验证了类

的大小为16。


参考书籍:深度探索C++对象模型





你可能感兴趣的:(C++,object,对象,内存布局)