首先来看看C++对象的内存模型:
为了节省内存,编译器在编译时会将成员函数和成员变量分开存储,每一个对象的成员变量都有其单独的存储空间,在堆区或者栈区分配内存,而所有对象的成员函数都共享一段内存空间,如下图所示:
对象的大小只受成员变量的影响,与成员函数无关。
#include<iostream>
#include<stdlib.h>
using namespace std;
class Dream
{
private:
int fight;
float insist;
char level='A';
public:
char GetLevel()
{
return level;
}
};
int main()
{
Dream *ptr=new Dream();//堆上创建对象
Dream baby;//栈上创建对象
cout<<sizeof(baby)<<endl;//求对象的内存大小;
cout<<sizeof(*ptr)<<endl;
cout<<sizeof(Dream)<<endl;//sizeof来求类的内存大小;
system("pause");
return 0;
}
dream类包含三个成员变量,都占4个字节(由于内存对齐(编译器的优化),方便寻址),而该类的对象baby内存大小也是12字节,可以有力证明对象内存只包含成员变量,如下图所示:
再来看看C++继承时对象模型:
class Success:public Dream
{
public:
int cool;
}//尽量简化代码,重点是关注内存模型;
Success adult;
则success的adult对象内存模型有下图:
当success再次派生时,派生对象的内存模型中的成员变量按照层级依次排列,新增的成员变量始终在最后。
在派生类的对象模型中,会包含所有基类的成员变量。这种设计方案的优点是访问效率高,能够在派生类对象中直接访问基类变量,无需经过好几层间接计算。
C++多继承时的内存模型其实也很类似,
class Fail
{
public:
int cry;
};
class Success:public Dream,public Fail
{
public:
int cool;
};
Success adult;
则success的adult对象内存模型有下图:
在虚继承和RTTI机制下的内存模型比较复杂,以后我会单独研究分析,相信一切难题都将迎刃而解。