1》首先建立一个基类Student类
头文件Student.h 如下:
#ifndef Student_h#define Student_h#include<string>using namespace std;/*基类Student头文件*/class Student{protected:int num;string name;float score;public:Student(int num,string name,float score);void display();//******这里没有声明为virtual};#endif
2》基类Student实现
Student.cpp
#include"Student.h"#include<iostream>Student::Student(int num, std::string name, float score){this->num=num;this->name=name;this->score=score;}void Student::display(){cout<<"num:"<<this->num<<endl;cout<<"name:"<<this->name<<endl;cout<<"score:"<<this->score<<endl;}
3》派生类Graduate类头文件
#ifndef Graduate_h#define Graduate_h#include"Student.h"/*派生类头文件,公有继承Student类,并增加新属性wage;*/class Graduate:public Student{protected:float wage;public:Graduate(int num,string name,float score,float wage);void display();};#endif
4》派生类Graduate实现
#include<iostream>#include"Graduate.h"Graduate::Graduate(int num, std::string name, float score,float wage):Student(num,name,score){this->wage=wage;}void Graduate::display(){cout<<"num:"<<this->num<<endl;cout<<"name:"<<this->name<<endl;cout<<"score:"<<this->score<<endl;cout<<"wage:"<<this->wage<<endl;}
5》测试
#include<iostream>#include"Student.h"#include"Graduate.h"using namespace std;int main(){Student stu(1001,"LI",78.9);Graduate gra(2001,"Wang",88.9,200.0);Student *p_stu=&stu;//声明基类Student类的指针并指向Student类的对象p_stu->display();//通过指针调用display函数。—正常输出stu的num,name,scorep_stu=&gra;//基类Student类的指针指向派生类Graduate类的对象(兼容赋值)p_stu->display();//通过指针调用display函数。—只能输出派生类中基类成员的值return 0;}
运行结果如下:
第二次只是输出了派生类中相应的基类成员,而派生类中新增的数据成员“wage”没有输出 。
6》如何才能使其输出呢(即实现多态性)
将基类Student类中的display函数声明为虚函数即可:virtual void display();
再次运行就可以发现,可以利用父类的指针(p_stu)指向子类的对象(gra),通过p_stu->display()即可调用子类的display函数了。
7》这种多态性也适用于析构函数中。
上述两个类均未给出析构函数的形式,其使用默认析构函数
当类中存在有动态分配的存储时,该类的对象析构时也要进行回收资源。这里为了实验,只是打印一句话。
分别在头文件和类实现中声明和实现该析构函数,,如下:
声明:
~Student();实现:
Student::~Student(){cout<<"executing Student destructor"<<endl;}
声明:
~Graduate();
实现:
Graduate::~Graduate(){cout<<"executing Student destructor"<<endl;}
在Main函数中有如下语句 :
Student *p_stu=new Graduate(3001,"zhang",88.7,300);p_stu->display();delete p_stu;
此时结果为:
可以看出,只执行了基类的析构函数,而没有执行派生类的析构函数。原因跟之前 介绍 的display()函数调用相同。
8》如何也能执行派生类的析构函数呢?
方法与之前介绍的display函数一样,使用虚函数,即使用虚析构函数。
将析构函数声明为虚函数:即在前面添加Virtual即可(只需要在基类中声明为Virtual即可,其派生类自动变为virtual)。
此时结果为:
对于沙漠中的旅行者,最可怕的不是眼前无尽的荒漠,而是心中没有绿洲。