简单继承成员布局
#include <iostream>
using namespace std;
class FAC //父类
{
public:
int m_fai;
int m_faj;
};
class MYACLS :public FAC //子类
{
public:
int m_i;
int m_j;
};
int main()
{
//第五节 单一继承下的数据成员布局
printf("FAC::m_fai = %d\n", &FAC::m_fai);
printf("FAC::m_faj = %d\n", &FAC::m_faj);
printf("MYACLS::m_fai = %d\n", &MYACLS::m_fai);
printf("MYACLS::m_faj = %d\n", &MYACLS::m_faj);
printf("MYACLS::m_i = %d\n", &MYACLS::m_i);
printf("MYACLS::m_j = %d\n", &MYACLS::m_j);
/*
打印偏移值:
FAC::m_fai = 0
FAC::m_faj = 4
MYACLS::m_fai = 0
MYACLS::m_faj = 4
MYACLS::m_i = 8
MYACLS::m_j = 12
*/
(1)一个子类对象,所包含的内容,是他自己的成员,加上他父类的成员的总和;
(2)从偏移值看,父类成员先出现,然后才是孩子类成员。
//FAC facobj;
//MYACLS myaclobj; //子类对象中实际上是包含着父类子对象的
return 1;
}
分别上述代码是父类和子类对象空间存储模型
复杂继承
#include <iostream>
using namespace std;
class Base
{
public:
int m_i1;
char m_c1;
char m_c2;
char m_c3;
};
class Base1
{
public:
int m_i1;
char m_c1;
};
class Base2 :public Base1
{
public:
char m_c2;
};
class Base3 :public Base2
{
public:
char m_c3;
};
int main()
{
cout << sizeof(Base1) << endl; //8
cout << sizeof(Base2) << endl; //12
cout << sizeof(Base3) << endl; //16
printf("Base3::m_mi1 = %d\n", &Base3::m_i1);
printf("Base3::m_mc1 = %d\n", &Base3::m_c1);
printf("Base3::m_mc2 = %d\n", &Base3::m_c2);
printf("Base3::m_mc3 = %d\n", &Base3::m_c3);
/*
vs输出:
8
12
16
Base3::m_mi1 = 0
Base3::m_mc1 = 4
Base3::m_mc2 = 8
Base3::m_mc3 = 12
*/
linux上windows上数据布局不一样,说明:
a)编译器在不断的进步和优化;
b)不同厂商编译器,实现细节也不一样;
c)内存拷贝就要谨慎;
/*
ubuntu输出:
8
12
12
Base3::m_mi1 = 0
Base3::m_mc1 = 4
Base3::m_mc2 = 8
Base3::m_mc3 = 9
*/
//Base2 mybase2obj;
//Base3 mybase3obj;
//你就不能用memcpy内存拷贝把Base2内容直接Base3里拷贝;
return 1;
}
左到右,分别是windows,vs下base1 ,base2, base3 布局
左到右,分别是linux下base1 ,base2, base3 布局
不能用memcpy内存拷贝把Base2内容直接Base3里拷贝(很明显base3的前12字节分布和base2不一样)