什么是C++虚函数、虚函数的作用和使用方法

我们知道,在同一类中是不能定义两个名字相同、参数个数和类型都相同的函数的,否则就是“重复定义”。但是在类的继承层次结构中,在不同的层次中可以出现名字相同、参数个数和类型都相同而功能不同的函数。

能否用同一个调用形式,既能调用派生类又能调用基类的同名函数。在程序中不是通过不同的对象名去调用不同派生层次中的同名函数,而是通过指针调用它们。例如,用同一个语句“pt->display( );”可以调用不同派生层次中的display函数,只需在调用前给指针变量 pt 赋以不同的值(使之指向不同的类对象)即可。

打个比方,你要去某一地方办事,如果乘坐公交车,必须事先确定目的地,然后乘坐能够到达目的地的公交车线路。如果改为乘出租车,就简单多了,不必查行车路线,因为出租车什么地方都能去,只要在上车后临时告诉司机要到哪里即可。如果想访问多个目的地,只要在到达一个目的地后再告诉司机下一个目的地即可,显然,“打的”要比乘公交车 方便。无论到什么地方去都可以乘同—辆出租车。这就是通过同一种形式能达到不同目的的例子。

C++中的虚函数就是用来解决这个问题的。虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。

(1)在基类用virtual声明成员函数为虚函数。这样就可以在派生类中重新定义此函数,为它赋予新的功能,并能方便被调用。
在类外定义虚函数时,不必在定义virtual

(2)在派生类中重新定义此函数,要求函数名,函数类型,函数参数个数和类型全部与基类的虚函数相同,并根据派生类的需要重新定义函数体。

c++规定,当一个成员函数被声明为虚函数后,其派生类的同名函数都自动成为虚函数。因此在派生类重新声明该

虚函数时,可以加virtual,也可以不加,但习惯上一般在每层声明该函数时都加上virtual,使程序更加清晰。

如果再派生类中没有对基类的虚函数重新定义,则派生类简单的继承起基类的虚函数。

(3)定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。
(4)通过该指针变量调用此虚函数,此时调用的就是指针变量指向的对象的同名函数。

#include<iostream>
#include<string>using namespace std;class Student
{public:Student(int , string, float);void display();protected:int num;string name;float score;
};
Student::Student(int n, string na, float s)
{num=n;name=na;score=s;
}
void Student::display()
{cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<endl;
}
class Graduate:public Student
{public:Graduate(int , string , float, float);void display();private:float pay;};
Graduate::Graduate(int n, string na, float s, float p):Student(n,na,s),pay(p)
{
}
void Graduate::display()
{cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\npay:"<<pay<<endl;}int main()
{Student stud1(110,"SDL",99.8);Graduate grad1(120,"CCT",88.9, 250.5);Student *p;p=&stud1;cout<<"student:"<<endl;p->display();p=&grad1;cout<<"graduate:"<<endl;p->display();return 0;
}

输出结果为:

此时没有将任何函数声明为虚函数,所以在Graduate类中diaplay()函数输出时没有pay的值,以为p指针是Student类的,本身Student不包括pay数据。

但如果我们想输出pay的值,只要把Student类中的display函数声明为虚函数即可,只要把它改为virtual void display()声明为虚函数就行,输出的结果为:

什么是C++虚函数、虚函数的作用和使用方法相关推荐

  1. c++,不能声明为虚函数的函数

    1.顶层函数:多态的运行期行为体现在虚函数上,虚函数通过继承方式来体现出多态作用,顶层 函数不属于成员函数,是不能被继承的. 2.构造函数: (1)构造函数不能被继承,因而不能声明为virtual函数 ...

  2. 虚函数 虚继承 抽象类

    虚函数.纯虚函数.虚基类.抽象类.虚函数继承.虚继承 虚函数:虚函数是C++中用于实现多态(polymorphism)的机制.核心理念就是通过基类访问派生类定义的函数.是C++中多态性的一个重要体现, ...

  3. 38.【C++ 虚函数 纯虚函数 虚基类 (最全详解)】

    虚函数.虚基类.纯虚函数 (一).虚函数 1.什么是虚函数: 2.虚函数的格式: 3.关于虚函数的注意事项: 4.虚函数的作用: 5.虚函数访问格式 6.虚函数的各种疑难杂症 [当指针是基类.但虚函数 ...

  4. c++ 函数模板_C/C++编程笔记:C++入门知识,深入解析C++函数和函数模板

    本篇要学习的内容和知识结构概览 函数的参数及其传递方式 1. 函数参数传递方式 传值: 传变量值: 将实参内存中的内容拷贝一份给形参, 两者是不同的两块内存 传地址值: 将实参所对应的内存空间的地址值 ...

  5. html中inline函数,开窗函数和窗口函数区别 inline函数和一般的函数有什么不同

    sql over开窗函数 和group by的区别 / 蓝讯如果有多个聚合函数,但是分组依据不同,此时只能使用开窗函数. 而GROUP BY要求聚合函数的分组依据一致. SQL Server中的开窗函 ...

  6. chi2inv函数 matlab_matlab函数列表(A~Z)【转】

    A a abs 绝对值.模.字符的ASCII码值 acos 反余弦 acosh 反双曲余弦 acot 反余切 acoth 反双曲余切 acsc 反余割 acsch 反双曲余割 align 启动图形对象 ...

  7. 类中成员函数的函数指针定义以及使用

    在algorithm算法中经常会碰到传递函数指针的情况,在这里面他们把这种类型叫做谓词,当然lambda表达式就是 谓词的一种.这次内容要说的当类的成员函数做为谓词时,是什么样子的,如何使用呢? 类中 ...

  8. Java箭头函数,lambda函数

    Java箭头函数,lambda函数 lambda表达式实质就是一种语法糖,(建议尽量不要使用lambda表达式,代码太简洁,难懂,难以调试) lambda表达式的简单例子: 不需要参数,返回5 ()- ...

  9. C++ 笔记(13)— 函数(函数声明、函数定义、函数调用[传值、指针、引用]、函数参数默认值、函数重载)

    每个 C++ 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数. 1. 函数声明 函数声明告诉编译器函数的名称.返回类型和参数.函数声明包括以下几个部分: ret ...

最新文章

  1. 考察新人的两道c语言题目
  2. rest-framework url控制
  3. web.xml中的那些标签和意义
  4. Jexus 5.8.2 正式发布为Asp.Net Core进入生产环境提供平台支持
  5. 7-26 Windows消息队列 (25 分)(详解+思路+超时解决)
  6. mqtt java_MQTT和Java入门
  7. Head first servlet and jsp学习笔记
  8. php 交换函数,php用于反转/交换数组中的键名和对应关联的键值的函数array_flip()...
  9. 中电信推大学生3G上网套餐
  10. 轨迹规划-二次规划QP
  11. win10和乌班图双系统卸载
  12. wordpress插件-wordpress常用插件大全
  13. java毕业设计新生宿舍管理系统Mybatis+系统+数据库+调试部署
  14. Guns二次开发(十四):集成 ueditor 富文本编辑器
  15. python和scre_python学习日志10
  16. java日志管理-学习(一)
  17. egg-shell-decorators 给你的蛋蛋加个壳
  18. 备忘4:爬取微博热门信息以及所有热门微博转发的用户信息
  19. (伟大的dfs)洛谷P4961 小埋与扫雷
  20. 每秒处理10万订单支付架构

热门文章

  1. OpenCV入门函数API解析
  2. python requests 状态码_requests获取所有状态码
  3. 重新激活“HTTP错误代码402”,释放Web 3.0的潜力(下)
  4. 1836:Alignment
  5. Caused by: javax.websocket.DeploymentException: Cannot deploy POJO class
  6. 光电转换模块_3月新品推荐:光电模块、MOSFET、光耦、电感
  7. Vue3 路由增加过度效果-淡入淡出
  8. python 腾讯企业邮箱 535, b'Error: authentication failed, system busy'
  9. 哈工大C语言程序设计精髓MOOC 第十三周编程题
  10. 利用java发送短信