//main.cpp
#include
#include "undergraduate.h"
#include "pupil.h"
using namespace std;
int main()
{
Undergraduate s1;
student s2;
Pupil s3;
student *sp=&s1;//sp指向本科生对象
s1.set("Tom",21,178,60);
sp->study();//体现多态性
sp=&s2; //sp指向学生对象
s2.set("Jon",22,185,68);
sp->study();//体现多态性
sp=&s3; //sp指向小学生对象
s3.set("Mike",8,148,45);
sp->study();//体现多态性
return 0;
}
运行结果:
Constructing a student without parameter…
Constructing a student without parameter…
Constructing a student without parameter…
学习高等数学和大学英语。
随便学些什么。
学习语数外。
我们看到,将学习设置为虚函数之后,无论对象指针sp指向哪种学生对象,sp->study()的执行结果总是与对应的类相符合的。多态就通过虚函数实现了。
我们在编写成员函数的时候,可以把尽可能多的成员函数设置为虚函数。这样做可以充分表现多态性,并且也不会给程序带来不良的副作用。
无法实现多态的虚函数
使用虚函数可以实现多态,但是如果在使用虚函数的同时再使用重载,就会可能使虚函数失效。我们修改程序17.7.1,看看重载会给虚函数带来些什么麻烦:(程序17.7.2)
//student.h
#include
using namespace std;
class student
{
public:
student(char *n,int a,int h,int w);
student();
void set(char *n,int a,int h,int w);
char * sname();
int sage();
int sheight();
int sweight();
virtual void study(int c=0);//设置为虚函数,带默认参数
protected:
char name ;//姓名
int age;//年龄
int height;//身高
int weight;//体重
};
……
void student::study(int c)
{
cout 《"随便学些什么。" < return;
}
//undergraduate.h和pupil.h同程序17.7.1
//main.cpp
#include
#include "undergraduate.h"
#include "pupil.h"
using namespace std;
int main()
{
Undergraduate s1;
student s2;
Pupil s3;
student *sp=&s1;
s1.set("Tom",21,178,60);
sp->study(1);//带参数
sp=&s2;
s2.set("Jon",22,185,68);
sp->study();
sp=&s3;
s3.set("Mike",8,148,45);
sp->study();
return 0;
}
运行结果:
Constructing a student without parameter…
Constructing a student without parameter…
Constructing a student without parameter…
随便学些什么。
随便学些什么。
随便学些什么。
当学生类的study成员函数和本科生类的study成员函数参数格式不同时,即使把学生类中的study设置为虚函数,编译器也无法找到本科生类中与之完全相同的study函数。多态是在程序员没有指定调用父类还是某个子类的成员函数时,电脑根据程序员的要求,揣测并选择最合适的成员函数去执行。但是当成员函数的参数格式不同时,程序员在调用成员函数的各种参数无疑就是在暗示到底调用哪个成员函数。这时电脑岂敢自作主张揣测人类的心思?因此,要使用虚函数实现多态性,至少要使各个函数的参数格式也完全相同。