1. 单一继承下数据成员布局
引入继承关系后,可能会带来内存空间的额外增加(字节对齐)
class A
{
public:
int a;
int b;
char c;
char d;
};
int main() {
cout << sizeof(A) << endl;
return 0;
}
- 结果:
class A
{
public:
int a;
int b;
};
class B:public A
{
public:
char b;
};
class C :public B
{
public:
char c;
};
int main() {
cout << sizeof(A) << endl;
cout << sizeof(B) << endl;
cout << sizeof(C) << endl;
return 0;
}
- 结果:
2. 单一继承(父类带、不带虚函数)的成员布局
class A
{
public:
int m_a;
virtual void funA() {};
};
class B : public A
{
public:
int m_b1;
int m_b2;
virtual void funB() {};
};
int main()
{
B b;
cout << sizeof(B) << endl;
printf("A::m_a= %d\n", &A::m_a);
printf("B::m_b1= %d\n", &B::m_b1);
printf("B::m_b2= %d\n", &B::m_b2);
b.m_a = 1;
b.m_b1 = 2;
b.m_b2 = 3;
return 0;
}
- 结果:
地址布局:
3. 多层继承数据布局
class A
{
public:
int m_a;
virtual void funA() {};
};
class B
{
public:
int m_b;
virtual void funB() {};
};
class C :public A, public B
{
public:
int m_c;
virtual void funC() {};
};
int main()
{
C c;
cout << sizeof(C) << endl;
printf("A::m_a= %d\n", &C::m_a);
printf("B::m_b= %d\n", &C::m_b);
printf("C::m_c= %d\n", &C::m_c);
c.m_a = 1;
c.m_b = 2;
c.m_c = 3;
return 0;
}
- 结果:
地址布局:
注:父类指针指向子列对象,父类指针的地址被调整为子类中父类对象地址
C c;
B* b = &c;
- c对象的地址:
- b指针指向的地址
可以看出b指向的地址向下调整了8个字节。。。
B* b = new C();
delete b; //发生异常(b指向的地址向下调整)
C* c = (C*)b;
delete c; //正常释放
- 更复杂的多层继承