一、类对象的内存布局
1.1、单一继承的类对象布局
示例1
class base
{
public:
int m_fai;
int m_faj;
};
class derive : public base
{
public:
int m_i;
int m_j;
};
int main()
{
base b;
derive d;
cout<<showbase;
cout<<hex<<&b.b_i<<endl;
cout<<&b.b_j<<endl;
cout<<&d.b_i<<endl;
cout<<&d.b_j<<endl;
cout<<&d.d_i<<endl;
cout<<&d.d_j<<endl;
return 0;
}
根据上述输出结果可以画出如下对象内存布局
示例2
class base1
{
public:
int b1_i;
char b1_c;
};
class base2 :public base1
{
public:
char b2_c;
};
class base3 :public base2
{
public:
char b3_c;
};
int main()
{
base3 b3;
cout<<showbase;
cout<<hex<<&b3.b1_i<<endl;
cout<<&b3.b1_c<<endl;
cout<<&b3.b2_c<<endl;
cout<<&b3.b3_c<<endl;
cout<<sizeof(base1)<<endl;
cout<<sizeof(base2)<<endl;
cout<<sizeof(b3)<<endl;
}
对象内存模型如下
通过上述模型可知,正常情况下,继承会增加对象所占的内存数,许多内存要用于内存补齐,增大程序的体积
1.2、单一含有虚函数的类对象布局
class base
{
public:
virtual void vfunc() {}
int bi;
};
int main()
{
base b;
printf("%d\n", &b);
printf("%d\n", &b.bi);
cout<<sizeof(base)<<endl;
}
1.3、单继承基类含有虚函数的内存布局
class base
{
public:
virtual void vfunc() {}
int bi;
};
class derive :public base
{
public:
int di;
int dj;
};
int main()
{
derive d;
printf("%d\n", &d);
printf("%d\n", &d.bi);
printf("%d\n", &d.di);
printf("%d\n", &d.dj);
cout<<sizeof(d)<<endl;
}
1.4、单继承基类含有虚函数的内存布局
class base
{
public:
int bi;
};
class derive :public base
{
public:
int di;
int dj;
virtual void vfunc() {}
};
int main()
{
derive d;
printf("%d\n", &d);
printf("%d\n", &d.bi);
printf("%d\n", &d.di);
printf("%d\n", &d.dj);
cout<<sizeof(d)<<endl;
}
对象内存布局同1.3
无论虚函数位于基类还是子类,对于单一继承来说,vptr都位于对象的最上方
1.5、多重继承的对象内存布局
class base
{
public:
virtual void b1vfunc() {}
int m_bi;
base(){
printf("base的this指针是:%p!\n", this);
}
};
class base2
{
public:
virtual void b2vfunc() {}
int m_b2i;
base2(){
printf("base2的this指针是:%p!\n", this);
}
};
class derive :public base, public base2
{
public:
int m_i;
int m_j;
virtual void dvfunc(){}
derive() {
printf("derive的this指针是:%p!\n", this);
}
};
int main()
{
derive d;
cout << sizeof(derive) << endl;
printf("derive::m_bi = %d\n", &d.m_bi);
printf("derive::m_b2i = %d\n", &d.m_b2i);
printf("derive::m_i = %d\n", &d.m_i);
printf("derive::m_j = %d\n", &d.m_j);
}
因为多重继承需要额外的内存存放vptr以及可能因为内存补齐而耗费多余的内存,所以,多重继承的代码占内存空间比一般继承要大
参考
《深度探索C++对象模型》
《C++新经典:对象模型》
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出