继承是实现多态的基础。虚函数是实现多态的方法。虚函数多态继承都是紧密相关的概念。而继承是所有概念的基础;

多态:简单来讲就是接口一样,实现多样。多态是指通过基类的指针或者引用,在运行时动态调用实际绑定对象函数的行为。与之相对应的编译时绑定函数称为静态绑定。多态是面向对象编程的核心思想之一。多态还有个关键之处就是一切用指向基类的指针或引用来操作对象

虚函数:刚才说到,指向基类的指针在操作它的多态类对象时,会根据不同类的对象,调用其相应的函数。这个函数就是虚函数。虚函数的虚是在于它的调用不是在编译时被确定的,而是在运行时被确定的。

虚函数就是在函数名声明前面加一个关键字 virtual

这里顺便阐述一个概念:联编

将源代码中的函数调用解释为特定的函数代码块被称为函数名联编(binding)。就像上方所说的“绑定”,是一回事。

编译器可以在编译过程中完成联编,这被称作静态联编。又称为早期联编。

虚函数使这项工作变得更加困难。使用哪个函数不是在编译时就能确定的,因为编译器不知道用户将选择哪个类型的对象。所以编译器必须生成能够在程序运行时选择正确的虚方法的代码,这被称为动态联编,又称为晚期联编

编译器对非虚方法使用静态联编。对虚方法采用动态联编。

因此我们可以理解虚函数的意义在于告诉编译器采用动态联编的方式。之所以这样做的目的还是为了服务于多态的要求。

虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism)。

C++的指导原则之一就是不要为不使用的特性付出代价(内存或处理时间)

而虚函数的技术,是会造成额外的开销,为了使程序能够在运行阶段进行决策,必须采用一些方法跟踪基类指针或引用指向的对象类型,这增加了额外的的处理开销。

使用静态联编的方式就更加高效,所以默认都是使用静态联编的方式

纯虚函数

为了方便实现多态特性,常常需要在基类中定义虚拟函数,但是往往基类是一种抽象类,其本身是不能被实例化的。
所以为了解决上述问题,引入纯虚函数的概念。

纯虚函数在基类中声明,但没有定义

但要求任何派生类都要定义自己的实现方法

使用方式就是:在基类函数原型后面加"=0"

====================================================

相关阅读:

如果期望派生类重新定义一个成员函数,应该在基类中把此函数设为virtual。

允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。

在基类用virtual声明成员函数为虚函数可以在派生类中重新定义此函数,为它赋予新的功能,并能方便地被调用。

如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函数。

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

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

纯虚函数

抽象类中的虚函数不打算被调用,不应该定义它,应该把它设置为纯虚函数(在函数声明之后加上'=0'即可);

基类不在基类中实现纯虚函数的方法是在函数原型后加“=0”

  virtual void funtion1()=0

纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。

拥有纯虚函数者为抽象类,以别于所谓的具体类;

抽象类不能产出对象实例,但是我们可以拥有指向抽象类的指针,以便于操作抽象类中的各个派生类。

为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。

在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。

为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重写以实现多态性。

同时含有纯虚拟函数的类称为抽象类,它不能生成对象。

更深层次的讨论:

纯虚函数是为你的程序制定一种标准即只要你继承了我,就必须按照我和标准来,实现我所有的方法否则你也是虚拟的,和JAVA里的接口一样,都是制定标准,为了使程序更加通用化可重用性提高,让所有实现它或继承自它的子类全部按同一标准来工作,你想想大家都按标准来对程序的益处是什么?

===================================================

相关文章传送门:

C++_了解虚函数的概念:https://www.cnblogs.com/grooovvve/p/10112085.html

C++_类继承3-动态联编和静态联编:https://www.cnblogs.com/grooovvve/p/10422296.html

=====================================================

相关链接:

多态的实现原理:https://blog.csdn.net/kwanson/article/details/80379360

多态(C++):https://blog.csdn.net/ijn842/article/details/80936236

C++Review1_多态和虚函数的更多相关文章

  1. C++中的多态与虚函数的内部实现

    1.什么是多态         多态性可以简单概括为“一个接口,多种行为”.         也就是说,向不同的对象发送同一个消息, 不同的对象在接收时会产生不同的行为(即方法).也就是说,每个对象可 ...

  2. C++多态、虚函数、纯虚函数、抽象类、虚基类

    一.C++多态 C++的多态包括静态多态和动态多态.静态多态包括函数重载和泛型编程,动态多态包括虚函数.静态多态是指在编译期间就可以确定,动态多态是指在程序运行时才能确定. 二.虚函数 1.虚函数为类 ...

  3. C++多态、虚函数、纯虚函数、抽象类

    多态 同一函数调用形式(调用形式形同)可以实现不同的操作(执行路径不同),就叫多态. 两种多态: (1)静态多态:分为函数重载和运算符重载,编译时系统就能决定调用哪个函数. (2)动态多态(简称多态) ...

  4. 《挑战30天C++入门极限》C++中类的多态与虚函数的使用

        C++中类的多态与虚函数的使用 类的多态特性是支持面向对象的语言最主要的特性,有过非面向对象语言开发经历的人,通常对这一章节的内容会觉得不习惯,因为很多人错误的认为,支持类的封装的语言就是支持 ...

  5. [c++] C++多态(虚函数和虚继承)

    转自:https://www.jianshu.com/p/02183498a2c2 面向对象的三大特性是封装.继承和多态.多态是非常重要的一个特性,C++多态基于虚函数和虚继承实现,本文将完整挖掘C+ ...

  6. C++ 多态与虚函数

    1.多态的概念 由虚函数实现的动态多态性就是:同一类族中不同类的对象,对同一函数调用作出不同的响应. 先看下面这个简单的例子: #include<iostream> using std:: ...

  7. C++中类的多态与虚函数的使用

    C++的三大特性:封装.继承.多态.以前学的时候自己没去总结,记得在一本c++入门的书讲得还是比较清楚.今天上网找了一下多态,找到下面这篇文章写得比较清晰. http://pcedu.pconline ...

  8. C++入门之初话多态与虚函数

    多态性是面向对象程序设计的又一个重要思想,关于多态的详尽描述,请看本人的收藏https://www.cnblogs.com/hust-ghtao/p/3512461.html.这篇博文中,详尽的探讨了 ...

  9. C++多态,虚函数,虚函数表,纯虚函数

    1.多态性   指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作. C++支持两种多态性:编译时多态性,运行时多态性.    a.编译时多态性:通过重载函数实现 ,模板(2次编译)  ...

随机推荐

  1. poj2112 最大流

    我用Dinic写的.G++ 1800ms 很慢,c++直接超时.优化后的 141ms,很快! 对于此题,建图方法很巧妙,通常想到求距离,那就会朝距离的方向建图,但是这题根据牛个数来建图,然后二分距离. ...

  2. 两种最常用的 HTTP 方法:GET 和 POST。

    什么是 HTTP? 超文本传输协议(HTTP)的设计目的是保证客户机与服务器之间的通信. HTTP 的工作方式是客户机与服务器之间的请求-应答协议. web 浏览器可能是客户端,而计算机上的网络应用程 ...

  3. 实用的cmd命令

    1.打开iis服务器:inetmgr 2.远程连接:mstsc 3.注册表:regedit.exe

  4. Nginx 缓存代理

    访问ArcGIS官网的地图瓦片太慢.想到可用NIGIX代理. Nginx是Linux下http代理软件,Windows下也有. 以下为配置方法,注意红色部分. 1.需要在本地proxy_cache_p ...

  5. 开发者必知的8款App快速开发工具开发者必知的8款App快速开发工具

    "我有一个好创意,就差一个CTO……" "原生APP开发难度大,周期长,成本高,还没上线市场已经被占领了." "APP版本迭代更新,都是企业的一道难关 ...

  6. react-cli

    更新日志: v1.2.0 ...未完待续 v1.1.0 添加editorconfig 配置ESLint 集成prettier 集成 lint-staged 实现细节: 添加editorconfig e ...

  7. day5-python之递归与二分法

    一.递归的定义 递归调用是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身,就是递归调用 二.递归分为两个阶段:递推,回溯 age(5) = age(4) + 2 age(4) = ag ...

  8. hdu 4114 Disney's FastPass(最短路+状态压缩)

    Disney's FastPass Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  9. Android图形子系统

    图形操作可以有两种方式实现:一是利用通用CPU模拟图形操作:二是利用GPU专门做图形操作.前者会增加CPU的负担,在现在高分辨率已经是普遍现象的时候,让通用处理器来完成大量的图形计算已经不现实.And ...

  10. [学习笔记]整体DP

    问题: 有一些问题,通常见于二维的DP,另一维记录当前x的信息,但是这一维过大无法开下,O(nm)也无法通过. 但是如果发现,对于x,在第二维的一些区间内,取值都是相同的,并且这样的区间是有限个,就可 ...