5.多重继承:
一个派生类同时继承多个基类,叫做多重继承。
声明多重继承的方法:
如果已声明了类A、类B和类C,可以声明多重继承的派生类D:
class D : public A,private B,proteced C
{类D新增加的成员};
多重继承派生类的构造函数:
派生类构造函数名(总参数列表):
基类1构造函数名(参数列表),
基类2构造函数名(参数列表),……
{ 派生类中新增数据成员初始化语句}
其中,< 总参数表 >中要包含所有基类构造函数中的参数;
调用基类构造函数的顺序按照声明时出现的顺序。
派生类构造函数的调用顺序:
①基类构造函数
②子对象成员类的构造函数(如果有子对象成员的话)
③派生类构造函数
派生类的析构函数:
析构函数也不能被继承,因而当派生类对象消亡调用派生类的析构函数时,基类的析构函数也将同时被调用。
派生类析构函数的执行顺序:
①派生类析构函数
②子对象成员类的析构函数(如果有子对象成员的话)
③基类析构函数
#include< iostream >
#include< string >
using namespace std;
class Teacher
{public:
Teacher(string nam,int a,string t)
{name=nam;age=a;title=t;}
void display();
protected:
string name;
int age;
string title;
};
class Student
{ protected:
string name1;
char sex;
float score;
public:
Student(string nam,char s,float sc):name1(nam),sex(s),score(sc) {}
void display();
};
class Graduate:public Teacher,public Student
{
protected:
float wage;
public:
Graduate (string nam,int a,string t, char s,float sc,float w):Teacher(nam,a,t),Student(nam,s,sc),wage(w){}
void show();
};
void Graduate::show()
{
cout<<"name:"<<name<<endl;
cout<<"age:"<<age<<endl;
cout<<"title:"<<title<<endl;
cout<<"sex:"<<sex<<endl;
cout<<"score:"<<score<<endl;
cout<<"wage:"<<wage<<endl;
}
int main()
{
Graduate grd1("Wang-li",24,"assistant",'f',89.5,1234.5);
grd1.show(); //调用派生类函数
return 0;
}
多重继承引起的二义性问题:
多重继承有效反映并处理现实复杂问题,却增加了程序编写和维护的难度。
例如,类C是类A、类B的直接派生类。讨论下面三种情况:
⑴ 两个基类有同名成员。
class A
{ public:
int a;
void display();
}
class B
{ public:
int a;
void display();
}
class C:public A,public B
{ public:
int b;
void show();
}
intmain()
{ C c1;
c1.a=3;//x
c1.display();//x
}
intmain()
{ C c1;
c1.A::a=3;
c1.A::display();// 正确
}
⑵ 两个基类和派生类都有同名成员。
class A
{ public:
int a;
void display();
}
class B
{ public:
int a;
void display();
}
class C :public A,public B
{ public:
int b;
void display();
}
int main()
{ C c1;
c1.a=3;//正确
c1.display();//正确
}
⑶ 如果类A和类B是从同一个基类N派生的。
#include< iostream >
using namespace std;
class N
{
public:
int a;
void display()
{
cout<<"A::a="<<a<<endl;
}
};
class A :public N
{ public:
int a1;
};
class B:public N
{ public:
int a2;
};
class C :public A,public B
{ public:
int b;
void show();
};
void C::show()
{
cout<<"A::a="<<A::a<<endl;
}
int main()
{
C c1;
c1.A::a=3;
c1.A::display();
c1.show();
}
虚基类:
虚基类方法使得在继承间接共同基类时只保留一份成员。
假设,A、B、C、D类呈左图继承关系,其成员情况如右图所示。类D保留了从B、C继承来的2份A类成员。
class A
{ ……};
//声明类B是类A的公有派生类,A是B的虚基类
class B :virtualpublic A
{ ……};
//声明类C是类A的公有派生类,A是C的虚基类
class C :virtualpublic A
{ ……};
!!!注意:虚基类并不是在声明基类时声明的,而是在声明派生类,指定继承方式时声明的。
虚基类声明的一般形式:
class 派生类名:virtual 继承方式 基类名
在派生类B和C做了上面的声明后,派生类D中的成员如下图:
基类A成员只保留一次继承。
!!!注意:
为保证虚基类在派生类中只继承一次,应当在该基类所有直接派生类中都声明为虚基类。否则仍会出现对基类的多次继承。
如下图,类D中没有声明类A为虚基类,则类E会保留对基类A成员的2次继承。