在C++中,有两种类的成员变量:static和非static,有三种成员函数:static、非static和virtual。那么,它们如何影响C++的对象在内存中的分布呢? 当存在继承的情况下,其内存分布又是如何呢?
下面就一个非常简单的类,通过逐渐向其中加入各种成员,来逐一分析上述两种成员变量及三种成员函数对类的对象的内存分布的影响。
注:以下的代码的测试结果均是基于Ubuntu 14.04 64位系统下的G++ 4.8.2,若在其他的系统上或使用其他的编译器,可能会运行出不同的结果。
注:以下的代码的测试结果均是基于Ubuntu 14.04 64位系统下的G++ 4.8.2,若在其他的系统上或使用其他的编译器,可能会运行出不同的结果。
1、含有非static成员变量及成员函数的类的对象的内存分布
类Persion的定义如下:
Person类包含两个非static的int型的成员变量,一个构造函数和一个非static成员函数。为弄清楚该类的对象的内存分布,对该类的对象进行一些操作如下:
其运行结果如下:
class Person
{
public:
Person():mId(0), mAge(20){}
void print()
{
cout << "id: " << mId
<< ", age: " << mAge << endl;
}
private:
int mId;
int mAge;
};
Person类包含两个非static的int型的成员变量,一个构造函数和一个非static成员函数。为弄清楚该类的对象的内存分布,对该类的对象进行一些操作如下:
int main()
{
Person p1;
cout << "sizeof(p1) == " << sizeof(p1) << endl;
int *p = (int*)&p1;
cout << "p.id == " << *p << ", address: " << p << endl;
++p;
cout << "p.age == " << *p << ", address: " << p << endl;
cout << endl;
Person p2;
cout << "sizeof(p2) == " << sizeof(p1) << endl;
p = (int*)&p2;
cout << "p.id == " << *p << ", address: " << p << endl;
++p;
cout << "p.age == " << *p << ", address: " << p << endl;
return 0;
}
其运行结果如下:
从上图可以看到类的对象的占用的内存均为8字节,使用普通的int*指针可以遍历输出对象内的非static成员变量的值,且两个对象中的相同的非static成员变量的地址各不相同。
据此,可以得出结论,在C++中,非static成员变量被放置于每一个类对象中,非static成员函数放在类的对象之外,且非static成员变量在内存中的存放顺序与其在类内的声明顺序一致。即person对象的内存分布如下图所示: