纯虚函数的多重继承
问题是在做实验指导时候发现的,题目如下:
【问题描述】定义描述学生的student类,包含受保护两个数据成员,分辨是描述姓名的,string类型和描述学号的,int类型,构造函数有两个形参,用于设定这两个数据成员的值,此外包含6个成员函数,用于设定姓名和学号的函数,void setnameid(), 用于显示姓名和学号的函数void displaynameid(),以及四个纯虚函数void setmajor() ,string getmajor() , void setadvisor() 和 string getadvisor();
由学生类派生本科生类understud,新增受保护数据成员,描述专业,string类型,构造函数具有三个形参,重新定义函数void setmajor() 和string getmajor(),用于设置专业和获取专业;
由本科生类派生研究生类poststud,新增私有数据成员,描述导师姓名,string类型,构造函数具有四个形参,且具有缺省值,学生姓名缺省值为“***”,学号缺省值为-1,专业缺省值为“###”,导师姓名缺省值为“&&&”,重新定义函数void setadvisor() 和 string getadvisor(),用于设置导师属性和获取导师属性值;
在主函数中定义相应的指针对象和普通对象,请问可以定义哪些(哪个)类的普通对象,为什么(在实验报告中回答),定义开关变量,int型,通过输入进行赋值,若该值为0,则输出研究生对象的默认属性值,若非零,则依次输入姓名、学号、专业和导师信息,并依次打印出来。
这里面涉及到纯虚数的多重继承,编写代码如下
#include<iostream>
#include<iomanip>
#include<cmath>
#include<string>
#define π 3.1415
using namespace std;
class student{
protected:
string name;
int sID;
public:
student(string n, int s);
student();
void setnameid();
void displaynameid();
virtual void setmajor()=0;
virtual string getmajor()=0;
virtual void setadvisor() = 0;
virtual string getadvisor() = 0;
};
student::student(string n, int s) :name(n), sID(s){}
student::student(){}
void student::setnameid()
{
cout << "请分别输入姓名和学号:" << endl;
cin >> name >> sID;
}
void student::displaynameid()
{
cout << "姓名:" << name << endl;
cout << "学号:" << sID << endl;
}
class understud :public student
{
protected:
string majoy;
public:
understud(string n, int s, string m);
void setmajor();
string getmajor();
};
understud::understud(string n, int s, string m) :student(n, s), majoy(m){}
void understud::setmajor()
{
cout << "请输入专业:" << endl;
cin >> majoy;
}
string understud::getmajor()
{
return majoy;
}
class poststud :public understud{
private:
string tname;
public:
poststud(string n="***",int s=-1, string m="###", string tn = "&&&");
void setadvisor();
string getadvisor();
};
poststud::poststud(string n, int s, string m, string tn) :understud(n, s, m), tname(tn){}
void poststud::setadvisor()
{
cout << "请输入导师姓名:" << endl;
cin >> tname;
}
string poststud::getadvisor()
{
return tname;
}
int main()
{
student *P = NULL;
//understud a;错误
poststud b;
P = &b;
int a;
cin >> a;
if (a == 0)
{
P->displaynameid();
cout << "专业:" << P->getmajor() << endl;
cout << "导师:" << P->getadvisor() << endl;
}
else
{
P->setnameid();
P->setmajor();
P->setadvisor();
P->displaynameid();
cout << "专业:" << P->getmajor() << endl;
cout << "导师:" << P->getadvisor() << endl;
}
}
编写之后发现,如果基类中有多个纯虚函数,而他的子代没有完全的重载这些纯虚函数,而是只是重载了一部分,那么这个子类仍为抽象类,这个子类再次往下继承,如果之后的子类完成了全部的纯虚函数负载,那么这个子类才能摆脱抽象类,如本体的student是抽象类,其子类understud仍为抽象类,understud的子类就摆脱了抽象类