摘要:本文主要向大家介绍了VC编程之VC++的多态性与虚函数,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。
本文主要向大家介绍了VC编程之VC++的多态性与虚函数,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。
多态性是面向对象程序设计的关键技术之一。利用多态性技术,可以调用同一个函数名的函数,实现完全不同的功能。若程序设计语言不支持多态性,不能称为面向对象的语言。
在C++中有两种多态性:
编译时的多态性:通过函数的重载和运算符的重载来实现的。
运行时的多态性:在程序执行前,无法根据函数名和参数来确定该调用哪一个函数,必须在程序执行过程中,根据具体情况来动态地确定。它是通过类继承关系和虚函数来实现的,目的也是建立一种通用的程序。
虚函数的定义
◆ 1、定义格式
虚函数是一个类的成员函数,定义格式如下:
virtual 返回类型 函数名(参数表);
说明:
关键字virtual指明该成员函数为虚函数。virtual仅用于类定义中,如虚函数在类外定义,不可加virtual。
当某一个类的一个类成员函数被定义为虚函数,则由该类派生出来的所有派生类中,该函数始终保持虚函数的特征。
当在派生类中重新定义虚函数(overriding a virtual function,亦译作超载或覆盖)时,不必加关键字virtual。但重新定义时不仅要同名,而且它的参数表和返回类型全部与基类中的虚函数一样,否则联编时出错。
虚函数与“产生派生类”的第二步——改造类成员,同名覆盖(override)相区别:如未加关键字virtual,则是普通的派生类中的新成员函数覆盖基类同名成员函数(当然参数表必须一样,否则是重载),可称为同名覆盖函数,它不能实现运行时的多态性。
◆ 2、通过虚函数实现多态性
虚函数怎样实现多态性?请参见下面2个例子。
①【例8.6】计算学分。可由本科生类派生出研究生类,但它们各自的从课程学时数折算为学分数的算法是不同的,本科生是16个学时一学分,而研究生是20个学时一学分。赋值兼容规则与自定义的复制构造函数。
#include<iostream>#include<string>using namespace std;class Student{ string coursename; //课程名
int classhour; //学时
int credit; //学分,未考虑0.5学分public:
Student(){coursename="#";classhour=0;credit=0;} virtual void Calculate(){credit=classhour/16;} void SetCourse(string str,int hour){
coursename=str;
classhour=hour;
} int GetHour(){return classhour;} void SetCredit(int cred){credit=cred;} void Print(){cout<<coursename<<'\t'<<classhour<<"学时"<<'\t'<<credit<<"学分"<<endl;}
};class GradeStudent:public Student{public:
GradeStudent(){}; void Calculate(){SetCredit(GetHour()/20);}
};int main(){
Student s,*ps;
GradeStudent g;
s.SetCourse("物理",80);
s.Calculate();
g.SetCourse("物理",80);
g.Calculate();
cout<<"本科生:"<<'\t';
s.Print();
cout<<"研究生:"<<'\t';
g.Print();
s.SetCourse("数学",160);
g.SetCourse("数学",160);
ps=&s;
ps->Calculate();
cout<<"本科生:"<<'\t';
ps->Print();
ps=&g;
ps->Calculate();
cout<<"研究生:"<<'\t';
ps->Print();
getchar(); return 0;
}
运行结果为:
本科生:物理 80学时 5学分
研究生:物理 80学时 4学分
本科生:数学 160学时 10学分
研究生:数学 160学时 8学分
分析:
第一行,学分是由Student类的成员函数Calculate()计算。
第二行,学分是由GradeStudent重新定义的Calculate()计算,它屏蔽了基类的同名函数。与不定义为虚函数一样,属编译时的多态性。
第三行,用的是指向Student类的对象s的指针,用的是Student类的Calculate()。
第四行,指针类型是指向基类的指针,但这里指针指向了派生类GradeStudent的对象g,按赋值兼容规则是准许的,但只能用基类的成员,可实际上用了派生类中新定义的Calculate()。这就是虚函数体现的多态性。如果不是虚函数,第四行输出是10学分。如果不使用基类指针指向派生类GradeStudent的对象g,也不能实现运行时的多态性。
②为体现虚函数的多态性的优点,可改造【例8.6】为
#include<iostream>#include<string>using namespace std;class Student{ string coursename; //课程名
int classhour; //学时
int credit; //学分,未考虑0.5学分public:
Student(){coursename="#";classhour=0;credit=0;} virtual void Calculate(){credit=classhour/16;} void SetCourse(string str,int hour){
coursename=str;
classhour=hour;
} int GetHour(){return classhour;} void SetCredit(int cred){credit=cred;}
void Print(){cout<<coursename<<'\t'<<classhour<<"学时"<<'\t'<<credit<<"学分"<<endl;}
};class GradeStudent:public Student{public:
GradeStudent(){}; void Calculate(){SetCredit(GetHour()/20);}
};void Calfun(Student &ps,string str,int hour){
ps.SetCourse(str,hour);
ps.Calculate();
ps.Print();
}int main(){
Student s;
GradeStudent g;
cout<<"本科生:";
Calfun(s,"物理",80);
cout<<"研究生:";
Calfun(g,"物理",80);//派生类对象初始化基类的引用,只有calculate()为虚函数才能实现动态的多态性
return 0;
}
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言VC/MFC频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号