c++远征之多态篇——虚函数及其实现原理

以下内容源于慕课网的学习整理,如有侵权,请告知删除。


 1、多态的定义

  • 简单理解,就是对于同一条命令,不同对象会做出不同的操作。
  • 相同对象收到不同消息,或者不同对象收到相同消息时,产生不同的动作。

2、多态的分类

(1)静态多态(早绑定)

  • 如函数重载,在编译阶段,(根据传参情况)就已经知道要执行哪个函数。


(2)动态多态(晚绑定)

a、虚函数

多态具体到语法上是

  • 父类和多个子类有同名函数;
  • 定义了父类指针并指向了子类对象,然后通过父类指针,调用子类中的同名函数,而非父类中的同名函数。
  • 动态多态,即父类调用子类的实现方式。

实现多态,需要将父类中的同名函数定义为虚函数

  • 虚函数,即在成员函数前(如析构函数前、普通成员函数前)添加关键字virtual。

 下面不是动态多态,因为main中调用的都是父类中的函数

     


     


为了实现调用子类中的同名函数,需要在父类的同名函数前添加关键字virtual,(建议在子类的同名函数前也添加virtual,但不是必须的)




b、虚析构函数

多态中存在的问题是内存泄漏问题,解决方法是虚析构函数。

  • 使用父类指针,去销毁子类对象时,会出现内存泄漏的问题。
  • 因为delet p(p是父类指针)时,执行的是父类的析构函数;
  • 而我们希望执行的是子类的析构函数。
  • 解决这个问题的方法是,在父类的析构函数前添加virtual,即虚析构函数。
  • 实际上,执行完子类的虚析构函数就会执行父类的析构函数。




c、virtual在函数中的使用限制

  • 普通函数不能是虚函数,必须是类的成员函数;
  • 静态成员函数不能是虚函数,如 virtual stact int getCount() 是错误的;
  • 内联函数不能是虚函数;
  • 构造函数不能是虚函数。


3、虚函数和虚析构函数的实现原理

(1)首先知道函数指针这个概念。



(2)虚函数表

  • 当父类有虚函数时,并且实例化一个父类对象时,会有一个虚函数表指针,指向了一个虚函数表。
  • 通过虚函数表得到虚函数指针,从而得到虚函数的入口地址。

   


  • 子类也有一个虚函数表,子类的虚函数表的首地址,一般和父类虚函数表的首地址不一样;
  • 假如子类中没有定义和父类同名的虚函数(如下),那么子类从父类中继承了虚函数,因此子类的虚函数表中的虚函数指针指向同一个虚函数入口。



  • 假如子类中定义了和父类同名的虚函数(如下),那么子类的虚函数将覆盖父类的虚函数。



(3)虚析构函数的实现原理

  • 前提(已知),执行完子类的虚析构函数就会自动执行父类的析构函数。
  • 子类中有虚析构函数(如果父类的析构函数用virtual修饰的话,则子类的虚构函数无论是否用virtual修饰,都是虚析构函数);
  • 父类指针通过子类的虚函数表指针,得到虚析构函数的入口地址,执行完子类的虚析构函数后,会自动执行父类的析构函数。

(4)证明虚函数表指针的存在?

(5)细节

  • 在c++中,多态的实现是通过虚函数表实现的;
  • 每个类只有一份虚函数表,所有该类的对象共用同一张虚函数表;
  • 两张函数表中的函数指针可能指向同一个函数。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461528.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++远征之多态篇——纯虚函数和抽象类、接口类

以下内容源于慕课网的学习整理,如有侵权,请告知删除。 1、纯虚函数 没有函数体;0;即只有函数声明,而没有函数定义的虚函数,是纯虚函数。 2、抽象类 概念:含有纯虚函数的类,叫抽象类…

W3 Total Cache+Hacklog Remote Attachment Upyun

2019独角兽企业重金招聘Python工程师标准>>> Hacklog Remote Attachment Upyun 是「荒野无灯」开发的WP插件,可以很方便的配合又拍云使用。通过这个插件,可以在添加媒体的时候上传至又拍云,对速度有极大的提升。 另外,…

VS2013崩溃,无法打开项目的解决方案

最近遇到VS2013,在打开解决方案时,报如下错误: “未找到与约束 ContractName Microsoft.Internal.VisualStudio.PlatformUI.ISolutionAttachedCollectionServiceRequiredTypeIdentity Microsoft.Internal.VisualStudio.PlatformUI.ISolutionA…

c++远征之多态篇——运行时类型识别(RTTI)

以下内容源于慕课网的学习整理,如有侵权,请告知删除。 1、RTTI(Run-Time Type Information),运行时类型识别。 涉及typeid、dynamic_cast这两个知识点。RTTI技术可以通过父类指针,识别其所指向对象的真实数…

用c#写的一个局域网聊天客户端 类似小飞鸽

最后在公司实习,新人不给活干,就自己随便看看,了解一些DevExpress控件啊,编码规范啊之类的,自己就寻思着写一点点小东西练习练习 出于自己对c# socket这块不熟,就选择了这块,顺便可以进一步了解…

c++远征之多态篇——异常处理

以下内容源于慕课网的学习整理,如有侵权,请告知删除。 1、关于异常的一些概念 异常:程序运行期出现的错误。 数组下标越界;除数为0;内存不足;…… 异常处理:对有可能发生异常的地方做出预见性的…

图像传感器之CMOS(2)

转:http://www.elecfans.com/application/Military_avionics/2013/0531/319531.html 提高宇航级图像传感器生产能力 日前,在能量效率方面不断创新的安森美半导体公司已同斯坦福国际研究院(SRI)和波尔航天科技公司合作,…

c++远征之模板篇——友元函数、友元类

以下内容源于慕课网的学习整理,如有侵权,请告知删除。 一、友元函数 1、分类 全局函数——》友元全局函数 成员函数——》友元成员函数 2、关键字friend 友元全局函数 如下,利用friend修饰的函数,其参数应该是本类的引用或者指…

PHP通过session判断防止表单重复提交实例

PHP通过session判断防止表单重复提交实例 PHP通过session判断防止表单重复提交实例,当用户提交表单后,为防止重复操作,通过session来判断是否为初次提交,否则让他返回到之前表单页面。 当前表单页面is_submit设为0 1 SESSION_STAR…

c++远征之模板篇——静态数据成员,静态成员函数

以下内容源于慕课网的学习整理,如有侵权,请告知删除。 1、静态数据成员 (1)不同于普通的数据成员,静态数据成员在没有实例化时,它也是存在的(即它是和类共存的); &…

c++远征之模板篇——运算符重载

以下内容源于慕课网的学习整理,如有侵权,请告知删除。 一、运算符重载的概念 给原有的运算符赋予新的功能。比如下面的截图,本来加号并不具备坐标的相加的功能,但是通过运算符重载可以实现该功能。 二、运算符重载的本质 本质是…

frp对http协议应用

前言 frp是一个开源的项目, 可用于内网穿透的高性能的反向代理应用,支持 tcp, udp 协议,为 http 和 https 应用协议提供了额外的能力,且尝试性支持了点对点穿透。 github地址:https://github.com/fatedier/frp 此处对http的应用做…

树形列(无限级联下拉列的曲线版本)

先上效果图: 1、列表 - 列表设置 - 创建栏,“类型”选择“托管元数据”,如下图: 2、选中“托管元数据”后,可以到下面编辑需要的树形啦: 3、编辑好,确定,搞定;可以到列表…

c++远征之模板篇——函数模板、类模板

以下内容源于慕课网的学习整理,如有侵权,请告知删除。 函数模板(vs模板函数) 1、为什么需要模板? 函数体相同,只是类型不一样而已。那么能否把数据的类型当做参数传递呢?肯定是可以的&#xff0…

c++远征之模板篇——标准模板库(STL)

以下内容源于慕课网的学习整理,如有侵权,请告知删除。 常见的设计模板 1、vector,向量 (1)本质是对数组的封装; (2)能够在常数时间内完成读取; (3&#xf…

数据结构探险——队列篇

以下内容源于慕课网的学习整理,如有侵权,请告知删除。 1、什么是队列? (1)先入先出的模型(FIFO)。 (2)队头,队尾。 (3)细分为普通队…

数据结构与算法之冒泡排序

转载于:https://www.cnblogs.com/yakun/p/3634457.html

数据结构探险——栈篇

以下内容源于慕课网的学习整理,如有侵权,请告知删除。 1、栈要素 栈底(不变)、栈顶(随着入栈和出栈而改变) 2、栈机制的实现 (1)栈的相关机制 判断栈的空满;入栈、出栈…

windows下修改tomcat的startup.bat脚本文件后台运行

1、修改startup.bat文件 rem Get remaining unshifted command line arguments and save them in the set CMD_LINE_ARGS :setArgs if ""%1"""""" goto doneSetArgs set CMD_LINE_ARGS%CMD_LINE_ARGS% %1 shift goto setArgs :doneSet…

开源框架:CocoaPods 安装学习教程

转载 开源框架:CocoaPods 引言: CocoaPods是一个可以帮你集中管理第三方库的开源项目,运行在Ruby的环境下,基于GitHub托管优势,你可以很方便的查阅目前依赖于CocoaPods的资源. 并且,CocoaPods是可靠,稳定,安全的.可以为你在使用第三方库资源时节省大部分的配置和部署时间.更专心…