VC编程之VC++的多态性与虚函数
小标 2018-08-28 来源 : 阅读 812 评论 0

摘要:本文主要向大家介绍了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频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程