----为了解决菱形继承(钻石继承)的问题的
菱形继承:
A 公共基类 (采用虚继承后,A叫做虚基类)
/ \
B C 中间子类
\ /
D 汇聚子类
![](https://i-blog.csdnimg.cn/blog_migrate/506a385a5244881cd77ac610c8c29f19.png)
菱形继承时,D类中会有双份儿的A类的成员,访问的时候有歧义,会报错
可以用虚继承的方式来解决这种问题
虚继承:
在生成中间子类的时候,继承方式前加上关键字 virtual ,这时就变成了虚继承
虚继承能保证在汇聚子类中只有一份公共基类的成员
格式:
class B:virtual public A{
}
例:
#include <iostream>
using namespace std;
class A{
protected:
int m_a;
public:
A(){}
A(int a):m_a(a){}
};
class B:virtual public A{
protected:
int m_b;
public:
B(){}
//此处初始化表中构造A 被省略
//但是构造函数还要有A,目的是实例化B对象时会需要
B(int a,int b):A(a),m_b(b){}
};
class C:virtual public A{
protected:
int m_c;
public:
C(){}
//此处初始化表中构造A 被省略
//但是构造函数还要有A,目的是实例化C对象时会需要
C(int a,int c):A(a),m_c(c){}
};
//构造函数调用顺序:
//先构造虚基类,中间子类的顺序和此处的书写顺序相同
//最后构造汇聚子类
//析构调用顺序与构造相反
class D:public B,public C{
protected:
int m_d;
public:
D(){}
//虚继承时需要在汇聚子类的构造函数的初始化表中
//调用公共基类的构造函数,完成从虚基类继承过来的成员的初始化
//虚继承时,通过中间子类构造虚基类的过程被省略
D(int a,int b, int c, int d):A(a),B(a,b),C(a,c),m_d(d){}
void show(){
cout<<m_a<<endl;
}
};
int main(int argc, const char *argv[])
{
D d1(10,20,30,40);
d1.show();
return 0;
}
我们平时用的iostream 就是典型的虚继承来的
istream:virtual public basic_ios
ostream:virtual public basic_ios
iostream:public istream,public ostream
练习:
设计一个Base类,包含成员 姓名 name 年龄 age 及相关函数
由Base类派生出 Leader 类,新增成员 职称 title 部门 department
再由Base类派生出 Engineer类,新增成员 等级 rand 专业 major
由Leader 和 Engineer类共同派生 老板 Boss 类
在Boss类中,添加函数,输出个人信息。
#include <iostream>
using namespace std;
class Base{
protected:
string name;//名字
int age;//年龄
public:
Base(){}
Base(string n_name, int a_age):name(n_name), age(a_age){}
};
class Leader:virtual public Base{
protected:
string title;//职称
string department;//部门
public:
Leader(){}
Leader(string n_name, int a_age,string t_title,string d_department):
Base(n_name,a_age),title(t_title),department(d_department){}
};
class Engineer:virtual public Base{
protected:
string qg_major;//专业
int rand;//等级
public:
Engineer(){}
Engineer(string n_name, int a_age,string m_qg_major,int r_rand):
Base(n_name,a_age),qg_major(m_qg_major),rand(r_rand){}
};
class Boss:public Leader,public Engineer{
public:
Boss(){}
Boss(string n_name, int a_age,string t_title,string d_department,string m_qg_major,int r_rand):
Base(n_name,a_age),
Leader(n_name,a_age,t_title,d_department),
Engineer(n_name,a_age,m_qg_major,r_rand){}
void show(){
cout<<name<<age<<title<<department<<qg_major<<rand<<endl;
}
};
int main(int argc, const char *argv[])
{
cout<<"请输入 "<<"name "<<"age "<<"title "<<"department "<<"qg_major "<<"rand "<<endl;
Boss d1("小明",20,"软件工程师","开发部","通信工程",3);
d1.show();
return 0;
}