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

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

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

虚函数就是在函数名声明前面加一个关键字 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. SSH applicationContext.xml import异常

    近期在项目上,遇到了一个问题.在配置applicationContext.xml使用<import>标签引入其他的xml文件时,导致项目启动时过慢.有时还会引起启动异常.后来查到是xml文 ...

  2. Java练习 SDUT-2253_分数加减法

    分数加减法 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 编写一个C程序,实现两个分数的加减法 Input 输入包含多 ...

  3. this的作用

    1.在一般函数方法中使用 this 指代全局  function test(){ this.x = 1; alert(this.x);  }  test(); // 1 2.作为对象方法调用,this ...

  4. axios细节之绑定到原型和axios的defaults的配置属性

    把axios绑定到原型 vue开发者一套很好用的实践,一般来说,实践如果能够让大部分人都接受,会逐渐成为一个默认的标准. // 把axios配置到原型上 Vue.prototype.$axios = ...

  5. WPF疑难杂症之一(3D场景)

    原文:WPF疑难杂症之一(3D场景) 最近2个月一直在学习WPF,在实际的开发中遇到下面一个3D场景有关的问题,我先给出问题代码:首先是在资源中定义了一个3D变换组:<Window x:Clas ...

  6. @bzoj - 4380@ [POI2015] Myjnie

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 有 n 家洗车店从左往右排成一排,每家店都有一个正整数价格 p[ ...

  7. 【BZOJ1227】[SDOI2009]虔诚的墓主人

    E. 虔诚的墓主人 题目描述 小W 是一片新造公墓的管理人.公墓可以看成一块N×M 的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地.当地的居民都是非常虔诚的基督徒,他们愿意提前 ...

  8. iptables SNAT与伪装

    Source NAT(SNAT)的主要應用,是让同一內部網路上的多部主机,可共用同一条Internet实体连線.直接与Internet相连的闸道器,可使用SNAT(搭配连線追蹤)来来改写內部网络与In ...

  9. 2019年CPS-J复赛题解

    题目涉及算法: 数字游戏:字符串入门题: 公交换乘:模拟: 纪念品:完全背包: 数字游戏:广搜/最短路. 数字游戏 题目链接:https://www.luogu.com.cn/problem/P566 ...

  10. Oracle - @和@@、&与&& 的区别

    2018-01-15 15:36:17 袭冷 阅读数 4783更多 分类专栏: DB   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接 ...