7-2 从Student类和Teacher类派生出Graduate类(pta)

题目内容:
已知基类Person定义如下:
class Person
{
char Name[20];
char Sex;
int Age;
public:
void Register(char name[],int age,char sex);
void ShowMe();
};
请通过继承的方法建立两个派生类,其中
派生类Teacher:
1.新增的数据成员有:
char Dept[20];
int Salary;
2.新增的成员函数有:
Teacher(char name[ ],int age,char sex,char dept[ ],int salary);
void Show() //显示新增数据成员
派生类Student:
1.新增的数据成员有:
char ID[12];
char Class[12];
2.新增的成员函数有:
Student(char name[ ],int age,char sex,char ID[ ],char Class[ ]);
void Show()//显示新增数据成员
请通过继承的方法从Teacher和Student中建立派生类Graduate,其中
1.新增的成员函数有:
Graduate(char name[ ],int age,char sex,char dept[ ],int salary,char id[ ],char classid[ ]);
2.重写的成员函数有:
void ShowMe()//显示数据成员,要求调用基类的Show和ShowMe
在主程序中建立一个派生类Graduate的对象,利用成员函数显示对象的数据成员。

输入格式:

Graduate对象的初始化信息
例如:
李木子 22 f 信息学院 3300 15035003 硕301

输出样例:

在这里给出相应的输出。例如:
班级 硕301
学号 15035003
姓名 李木子
性别 女
年龄 22
工作单位 信息学院
月薪 3300


7-2 从Student类和Teacher类派生出Graduate类(pta)


这样的派生类Graduate类对象初始化时会出现两个一样的Person类(即有两份Person类拷贝)

当Graduate类要对象使用Person类的函数时,会发现运行出错

[Error] ‘Person’ is an ambiguous base of ‘Graduate’



方法1:使用Student或Teacher中的Person的函数;

#include <iostream>
#include <cstring>
using namespace std;
class Person {
char Name[20];
char Sex;
int Age;
public:
void Register(char name[],int age,char sex);
void ShowMe();
};
void Person::Register(char name[],int age,char sex){
 strcpy(Name,name);
 Age=age;Sex=sex;
}
void Person::ShowMe(){
 cout<<"姓名 "<<Name<<endl;
 cout<<"性别 "<<(Sex=='m'?"男":"女")<<endl;
 cout<<"年龄 "<<Age<<endl;
} 
class Teacher:public Person{
 char Dept[20];
int Salary;
public:
 Teacher(char name[ ],int age,char sex,char dept[ ],int salary);
void Show(); //显示新增数据成员
};
Teacher::Teacher(char name[ ],int age,char sex,char dept[ ],int salary)
{
 Person::Register(name,age,sex);
 strcpy(Dept,dept);
 Salary=salary;
}
void Teacher::Show(){
 cout<<"工作单位 "<<Dept<<endl;
 cout<<"月薪 "<<Salary<<endl;
}
class Student:public Person{
 char ID[12];
char Class[12];
public:
 Student(char name[ ],int age,char sex,char ID[ ],char Class[ ]);
void Show();//显示新增数据成员
};
Student::Student(char name[ ],int age,char sex,char id[ ],char classname[ ])
{
 Person::Register(name,age,sex);
 strcpy(ID,id);
 strcpy(Class,classname);
}
void Student::Show(){
 cout<<"班级 "<<Class<<endl;
 cout<<"学号 "<<ID<<endl;
}
class Graduate:public Student ,public Teacher{
 public:
  Graduate(char name[ ],int age,char sex,char dept[ ],int salary,char id[ ],char classid[ ]);
  void ShowMe();//显示数据成员,要求调用基类的Show和ShowMe 
};
Graduate::Graduate(char name[ ],int age,char sex,char dept[ ],int salary,char id[ ],char classid[ ])
:Student(name,age,sex,id,classid),Teacher(name,age,sex,dept,salary){}
void Graduate::ShowMe()
{
 Student::Show();
 Student::ShowMe();
 Teacher::Show();
}
int main()
{
 char name[20],dept[20],sex,id[12],classid[12];
 int age,salary;
 cin>>name>>age>>sex>>dept>>salary>>id>>classid;
 Graduate G(name,age,sex,dept,salary,id,classid);
 G.ShowMe();
 return 0;
}



虽然方法一能解决该情况,但是并没有改变派生类Graduate类对象初始化时会出现两个一样的Person类(即有两份Person类拷贝)的情况;
故在此引出虚基类,当使用了虚基类时,派生类Graduate类对象初始化时只有一份Person类的拷贝。故可以在Graduate类中直接显示使用Person函数。
方法二:使用虚基类

#include <iostream>
#include <cstring>
using namespace std;
class Person {
char Name[20];
char Sex;
int Age;
public:
void Register(char name[],int age,char sex);
void ShowMe();
};
void Person::Register(char name[],int age,char sex){
 strcpy(Name,name);
 Age=age;Sex=sex;
}
void Person::ShowMe(){
 cout<<"姓名 "<<Name<<endl;
 cout<<"性别 "<<(Sex=='m'?"男":"女")<<endl;
 cout<<"年龄 "<<Age<<endl;
} 
class Teacher:virtual public Person{
 char Dept[20];
int Salary;
public:
 Teacher(char name[ ],int age,char sex,char dept[ ],int salary);
void Show(); //显示新增数据成员
};
Teacher::Teacher(char name[ ],int age,char sex,char dept[ ],int salary)
{
 Person::Register(name,age,sex);
 strcpy(Dept,dept);
 Salary=salary;
}
void Teacher::Show(){
 cout<<"工作单位 "<<Dept<<endl;
 cout<<"月薪 "<<Salary<<endl;
}
class Student:virtual public Person{
 char ID[12];
char Class[12];
public:
 Student(char name[ ],int age,char sex,char ID[ ],char Class[ ]);
void Show();//显示新增数据成员
};
Student::Student(char name[ ],int age,char sex,char id[ ],char classname[ ])
{
 Person::Register(name,age,sex);
 strcpy(ID,id);
 strcpy(Class,classname);
}
void Student::Show(){
 cout<<"班级 "<<Class<<endl;
 cout<<"学号 "<<ID<<endl;
}
class Graduate:public Student ,public Teacher{
 public:
  Graduate(char name[ ],int age,char sex,char dept[ ],int salary,char id[ ],char classid[ ]);
  void ShowMe();//显示数据成员,要求调用基类的Show和ShowMe 
};
Graduate::Graduate(char name[ ],int age,char sex,char dept[ ],int salary,char id[ ],char classid[ ])
:Student(name,age,sex,id,classid),Teacher(name,age,sex,dept,salary){}
void Graduate::ShowMe()
{
 Student::Show();
 Person::ShowMe();
 Teacher::Show();
}
int main()
{
 char name[20],dept[20],sex,id[12],classid[12];
 int age,salary;
 cin>>name>>age>>sex>>dept>>salary>>id>>classid;
 Graduate G(name,age,sex,dept,salary,id,classid);
 G.ShowMe();
 return 0;
}

但是,因为Graduate类的Person的拷贝从原来的2个变成1个,会对Student或Teacher类对象使用Person类的函数产生影响吗?会出现错误吗?

将上面的代码的主函数进行更改

int main()
{
 char name[20],dept[20],sex,id[12],classid[12];
 int age,salary;
 cin>>name>>age>>sex>>dept>>salary>>id>>classid;
 Graduate G(name,age,sex,dept,salary,id,classid);
 G.ShowMe();
 cout<<"************************"<<endl;
 Student S(name,age,sex,id,classid);
 S.ShowMe();
 S.Show();
 cout<<"************************"<<endl;
 Teacher T(name,age,sex,dept,salary);
 T.ShowMe();
 T.Show();
 return 0;
}

7-2 从Student类和Teacher类派生出Graduate类(pta)