C++学习之继承

来源:互联网 发布:内蒙古财经大学网络 编辑:程序博客网 时间:2024/05/09 20:56

继承:使程序代码的重用度大幅度地提高了,而C++对继承有很好的支持,

基类对象不能给子类对象赋值,因为基类中的数据不充分,不含有子类全部的信息,
但是子类对象可以给基类对象赋值。

如下图所示:

例如:
student是一类,GraduateStudent是student的子类,那么
GraduateStudent gs;
Student* p = &gs;

由于p是Student指针,指向GraduateStudent对象gs的首地址,它恰好也是其中Student对象部分的首地址。

因为研究生也是学生,所以研究生对象gs赋值给s也是合理的。它裁去了专属研究生的部分,而且将研究生对象的地址赋给学生指针p也是合理的,由于学生对象地址和研究生对象地址重合,所以,p指针若转换为研究生类型是:
GraduateStudent* pGs = reinterpret_cast<GraduateStudent*>(p);
便无需修改地址就可以操作研究生了,这种reinterpret_cast转换,纯粹是地址不变而指针类型改变,即指针操作的意义改变。但前提是学生对象与研究生对象地址重合。

1. 覆盖父类操作

如果父类中有一个操作,在子类中没有重新定义,则子类可以沿用该操作,但都是父类操作。例如下列程序中,研究生类GraduateStudent继承了Student类,对象gs在显示其本人信息时,没有办法显示相关的研究生信息。这主要是GraduateStudent类中没有重载display成员函数,为了准备使用GraduateStudent类,需要在GraduateStudent类中把父类中的display成员函数进行覆盖。

#include <iostream>#include <string>using namespace std;class Advisor{int noOfMeeting;};class Student{string name;int semesterHours;double average;public:Student(string pName = "noName"){name = pName;average = 0;semesterHours = 0;}void addCourse(int hours, double grade){double totalGrade = (semesterHours * average + grade);semesterHours += hours;average = semesterHours ? totalGrade / semesterHours : 0;}void display(){cout << "name=\"" << name << "\"" << ", hours=" << semesterHours << ", average=" << average << endl;}int getHours(){return semesterHours;}double getAverage(){return average;}};class GraduateStudent : public Student{Advisor advisor;int qualifierGrade;public:GraduateStudent(string pName = "noName"):Student(pName){qualifierGrade = 0;}int getQualifier(){return qualifierGrade;}void display(){Student::display();cout << "qualifierGrade=" << qualifierGrade << endl;}};int main(){Student ds("Lo lee undergraduade");GraduateStudent gs("WU fantasy");ds.addCourse(3, 2.5);ds.display();gs.addCourse(3, 3.0);gs.display();return 0;}


2. 同化效应

在上述代码中,GraduateStudent类继承了Student类,当以自己的身份表现时,显示了自身的特色。但是,当以研究生对象复制(传递)给学生时,研究生的个性消失了,如下代码所示:

void fun(Student& x){x.display();}int main(){Student s("Lo lee undergraduate");GraduateStudent gs("John");fun(s);fun(gs);return 0;}

代码输出如下:

name="Lo lee undergraduate", hours=0, average=0name="John", hours=0, average=0

从输出结果可以看出,Student类对象s和GraduateStudent类对象gs作为参数传递给fun函数时,gs在fun函数中并不被看作为研究生,而被看作Student类对象进行操作。