多重继承派生类的构造函数形式与单继承时的构造函数形式基本相同,只是在初始表中包含多个基类构造函数。如
派生类构造函数名(总参数表列):基类1构造函数(参数表列),基类2构造函数(参数表列),基类3构造函数(参数表列){派生类中新增数成员据成员初始化语句}
各基类的排列顺序任意。
派生类构造函数的执行顺序同样为:先调用基类的构造函数,再执行派生类构造函数的函数体。调用基类构造函数的顺序是按照声明派生类时基类出现的顺序。
例11.8 声明一个教师(Teacher)类和一个学生(Student)类,用多重继承的方式声明一个研究生(Graduate)派生类。
教师类中包括数据成员name(姓名)、age(年龄)、title(职称)。
学生类中包括数据成员name1(姓名)、age(性别)、score(成绩)。
在定义派生类对象时给出初始化的数据,然后输出这些数据。
- #include <iostream>
- #include <string>
- using namespace std;
- class Teacher//声明类Teacher(教师)
- {
- public ://公用部分
- Teacher(string nam,int a, string t)//构造函数
- {
- name=nam;
- age=a;
- title=t;
- }
- void display( )//输出教师有关数据
- {
- cout<<″name:″<<name<<endl;
- cout<<″age″<<age<<endl;
- cout<<″title:″<<title<<endl;
- }
- protected ://保护部分
- string name;
- int age;
- string title;//职称
- };
- class Student//定义类Student(学生)
- {
- public :
- Student(char nam[],char s,float sco)
- {
- strcpy(name1,nam);
- sex=s;
- score=sco;
- }//构造函数
- void display1( )//输出学生有关数据
- {
- cout<<″name:″<<name1<<endl;
- cout<<″sex:″<<sex<<endl;
- cout<<″score:″<<score<<endl;
- }
- protected ://保护部分
- string name1;
- char sex;
- float
- score;//成绩
- };
-
- class Graduate:public Teacher,public Student //声明多重继承的派生类Graduate
- {
- public:
- Graduate(string nam,int a,char s, string t,float sco,float w):Teacher(nam,a,t),Student(nam,s,sco),wage(w) { }
- void show( ) //输出研究生的有关数据
- {
- cout<<″name:″<<name<<endl;
- cout<<″age:″<<age<<endl;
- cout<<″sex:″<<sex<<endl;
- cout<<″score:″<<score<<endl;
- cout<<″title:″<<title<<endl;
- cout<<″wages:″<<wage<<endl;
- }
- private: float wage; //工资
- };
- int main( )
- {
- Graduate grad1(″Wang-li″,24,′f′,″assistant″,89.5,1234.5);
- grad1.show( );
- return 0;
- }
程序运行结果如下:
在两个基类中分别用name和name1来代表姓名,其实这是同一个人的名字,从Graduate类的构造函数中可以看到总参数表中的参数nam分别传递给两个基类的构造函数,作为基类构造函数的实参。
解决这个问题有一个好方法:
在两个基类中可以都使用同一个数据成员名name,而在show函数中引用数据成员时指明其作用域,如
cout<<″name:″<<Teacher::name<<endl;
这就是惟一的,不致引起二义性,能通过编译,正常运行。
通过这个程序还可以发现一个问题:在多重继承时,从不同的基类中会继承一些重复的数据。如果有多个基类,问题会更突出。在设计派生类时要细致考虑其数据成员,尽量减少数据冗余。