上一篇中我们一起探索了继承的权限问题https://blog.csdn.net/a15929748502/article/details/80796483,这一篇我们来一起探索继承体系下派生类的对象模型是什么样的呢?
首先什么是对象模型呢,对象模型就是对象中非静态成员变量在内存中的布局
1.下面我们就从最简单的单继承开始研究,
什么是单继承呢,简单地说就是一个派生类只有一个父类
码出如下代码
#include <iostream>
using namespace std;
class Base //基类
{
public:
int _b;
};
class Derived :public Base //继承
{
public:
int _d;
};
int main()
{
Derived d;
d._b=1;
d._d=2;
cout<<*((int*)&d)<<endl; //打印出模型中的第一个元素
cout<<*((int*)&d+1)<<endl; //打印出模型中的第二个元素
cout << sizeof(Base) << endl; //4
cout << sizeof(Derived) << endl; //8
return 0;
}
编译后打印出的结果为
[root@localhost C++]# ./a.out
1
2
4
8
可以说明
D的对象模型中,基类成员在上+派生类自己的成员在下
D大小为8个字节,基类成员大小加上派生类成员大小
编译器没有为派生类合成构造函数
图示为
2.多继承
什么是多继承呢,简单的来说就是一个派生类有多个父类
include <iostream>
using namespace std;
class Base1 //基类
{
public:
int _b1;
};
class Base2 //基类
{
public:
int _b2;
};
class Derived :public Base1,public Base2 //继承
{
public:
int _d;
};
int main()
{
Derived d;
d._b1=1;
d._b2=2;
d._d=3;
cout<<*((int*)&d)<<endl;
cout<<*((int*)&d+1)<<endl;
cout<<*((int*)&d+2)<<endl;
cout << sizeof(Base1) << endl; //4
cout << sizeof(Base2) << endl; //4
cout << sizeof(Derived) << endl; //12
return 0;
}
打印结果是
[root@localhost C++]# ./a.out
1
2
3
4
4
12
可以看出多继承与单继承对象模型类似基类成员在上+派生类自己的成员在下
D大小基类成员大小加上派生类成员大小。
读者可以自行验证
3.菱形继承
菱形就比较复杂了,这里我画了一个示意图希望可以帮大家理解
这样看简单的来说,菱形继承就是一个先单继承,再多继承的过程
我们可以码出如下代码
#include <iostream>
using namespace std
class B
{
public:
int _b;
};
class C1: public B
{
public:
int _c1;
};
class C2 : public B
{
public:
int _c2;
};
class D : public C1, public C2
{
public:
int _d;
};
int main()
{
D d;
d._b=1;
d._c1=2;
d._c2=3;
d._d=4;
cout<<*((int*)&d)<<endl;
cout<<*((int*)&d+1)<<endl;
cout<<*((int*)&d+2)<<endl;
cout<<*((int*)&d+3)<<endl;
cout << sizeof(B) << endl; //4
cout << sizeof(C1) << endl; //8
cout << sizeof(C2) << endl; //8
cout << sizeof(D) << endl; //20
return 0;
}
这段代码看起来是没有问题的,但是在编译时就发生了错吴
C1++.cpp:27: error: request for member ‘_b’ is ambiguous
C1++.cpp:6: error: candidates are: int B::_b
C1++.cpp:6: error: int B::_b
编译器不可以确定是哪一个,下面我将对代码进行修改(在主函数中)
int main()
{
D d;
d.C1::_b=1;
d.C2::_b=2;
d._c1=3;
d._c2=4;
d._d=5;
cout<<*((int*)&d)<<endl;
cout<<*((int*)&d+1)<<endl;
cout<<*((int*)&d+2)<<endl;
cout<<*((int*)&d+3)<<endl;
cout<<*((int*)&d+4)<<endl;
cout << sizeof(B) << endl; //4
cout << sizeof(C1) << endl; //8
cout << sizeof(C2) << endl; //8
cout << sizeof(D) << endl; //20
return 0;
}
这次就可以通过了,打印的结果是
[root@localhost C++]# ./a.out
1
3
2
4
5
4
8
8
20
由此我们可以看出D的对象模型
大小为20个字节
基类的成员变量在派生类中存了两份
这显然是不合理的,那么应该怎样解决呢,下一篇虚拟继承我会和大家继续探讨的