解答了我的一些疑问,觉得写的不错!!!转载一下。

virtual在英文中表示“虚”、“虚拟”的含义。c++中的关键字“virtual”主要用在两个方面:虚函数与虚基类。下面将分别从这两个方面对virtual进行介绍。
1.虚函数

虚函数源于c++中的类继承,是多态的一种。在c++中,一个基类的指针或者引用可以指向或者引用派生类的对象。同时,派生类可以重写基类中的成员函数。这里“重写”的要求是函数的特征标(包括参数的数目、类型和顺序)以及返回值都必须与基类中的函数一致。如下所示:

可以在基类中将被重写的成员函数设置为虚函数,其含义是:当通过基类的指针或者引用调用该成员函数时,将根据指针指向的对象类型确定调用的函数,而非指针的类型。如下,是未将test()函数设置为虚函数前的执行结果:

在将test()函数设置为virtual后,执行结果如下:

如此,便可以将基类与派生类的同名方法区分开,实现多态。

说明:

1.只需将基类中的成员函数声明为虚函数即可,派生类中重写的virtual函数自动成为虚函数;

2.基类中的析构函数必须为虚函数,否则会出现对象释放错误。以上例说明,如果不将基类的析构函数声明为virtual,那么在调用delete p2;语句时将调用基类的析构函数,而不是应当调用的派生类的析构函数,从而出现对象释放错误的问题。

3.虚函数的使用将导致类对象占用更大的内存空间。对这一点的解释涉及到虚函数调用的原理:编译器给每一个包括虚函数的对象添加了一个隐藏成员:指向虚函数表的指针。虚函数表(virtual function table)包含了虚函数的地址,由所有虚函数对象共享。当派生类重新定义虚函数时,则将该函数的地址添加到虚函数表中。无论一个类对象中定义了多少个虚函数,虚函数指针只有一个。相应地,每个对象在内存中的大小要比没有虚函数时大4个字节(32位主机,不包括虚析构函数)。如下:

cout<<sizeof(base)<<endl;                        //12
    cout<<sizeof(inheriter)<<endl;                   //12

base类中包括了两个整型的成员变量,各占4个字节大小,再加上一个虚函数指针,共计占12个字节;inheriter类继承了base类的两个成员变量以及虚函数表指针,因此大小与基类一致。如果inheriter多重继承自另外一个也包括了虚函数的基类,那么隐藏成员就包括了两个虚函数表指针。

4.重写函数的特征标必须与基类函数一致,否则将覆盖基类函数;

5.重写不同于重载。我对重载的理解是:同一个类,内部的同名函数具有不同的参数列表称为重载;重写则是派生类对基类同名函数的“本地改造”,要求函数特征标完全相同。当然,返回值类型不一定相同(可能会出现返回类型协变的特殊情况)。
2.虚基类

在c++中,派生类可以继承多个基类。问题在于:如果这多个基类又是继承自同一个基类时,那么派生类是不是需要多次继承这“同一个基类”中的内容?虚基类可以解决这个问题。

简而言之,虚基类可以使得从多个类(它们继承自一个类)中派生出的对象只继承一个对象。虚继承的写法如下:

base称为mytest类的虚基类。假设base还是另外一个类mytest2的虚基类,对于多重继承mytest和mytest2的子类mytest3而言,base的部分只继承了一次。如下:


     
    cout<<sizeof(mytest)<<endl;                  //输出12
    cout<<sizeof(mytest2)<<endl;                 //输出12
    cout<<sizeof(mytest3)<<endl;                 //输出16,若在base中添加一个int型成员,则输出20

mytest类与mytest2类的大小为什么是12?这是因为它们在虚继承自base类后,添加了一个隐藏的成员——指向虚基类的指针,占4个字节。而base类本身占8个字节,因此它们的大小均为12。而对非虚继承而言,是不需要这样的一个指针的。而mytest3类的大小为sizeof(base)+sizeof(mytest-base)+sizeof(mytest2-base),即16。

说明:

1.若一个类多重继承自具有同一个基类的派生类时,调用同名成员函数时会出现二义性。为了解决这个问题,可以通过作用域解析运算符澄清,或者在类中进行重新定义;

2.继承关系可能是非常繁复的。一个类可能多重继承自别的类,而它的父类也可能继承自别的类。当该类从不同的途径继承了两个或者更多的同名函数时,如果没有对类名限定为virtual,将导致二义性。当然,如果使用了虚基类,则不一定会导致二义性。编译器将选择继承路径上“最短”的父类成员函数加以调用。该规则与成员函数的访问控制权限并不矛盾。也就是说,不能因为具有更高调用优先级的成员函数的访问控制权限是"private",而转而去调用public型的较低优先级的同名成员函数。
3.纯虚函数

若一个类的成员函数被声明为纯虚函数,则意味着该类是ABC(Abstract Base Class,抽象基类),即只能被继承,而不能用来声明对象。纯虚函数通常需要在类声明的后面加上关键词“=0”。

当然,声明为纯虚函数并不意味着在实现文件中不可对其进行定义,只是意味着不可用抽象基类实现一个具体的对象。

原文连接:https://blog.csdn.net/xbb123456rt/article/details/81986691

C++ Virtual 完美诠释相关推荐

  1. 白鹭安装node_Node.js大会 白鹭时代完美诠释Egret Wing解放HTML5生产力

    原标题:Node.js大会 白鹭时代完美诠释Egret Wing解放HTML5生产力 上周六,白鹭时代Egret Wing项目负责人张晨,参加了Node.js大会,并在大会上作了"使用 No ...

  2. slash php,Slash音色完美诠释

    作者--cyazomm 在这里不想强调什么神丹妙药和包抄小道,和众多朋友一起去想象一下音色的构成和质地才是最终的目的. 想得到SLASH一样的音色其实并不是很困难而是难在怎么去模仿,因为多数朋友都对S ...

  3. Python 完美诠释“高内聚“概念的 IO 流 API 体系结构

    1. 前言 第一次接触 Python 语言的 IO API 时,是惊艳的.相比较其它语言所提供的 IO 流 API . 无论是站在使用者的角度还是站在底层设计者的角度,都可以称得上无与伦比. 很多人在 ...

  4. 完美诠释中国智造 京东家电携合作伙伴闪耀AWE

    3月14日,作为全球瞩目的三大消费电子和家电展会之一,中国家电及消费电子博览会(简称AWE)在上海开幕,京东作为唯一受邀的零售平台参与此次盛会. 作为中国家电产业互联网升级转型的引领者,京东一直与AW ...

  5. Python 必知的20个神操作,完美诠释其简洁、优美的初衷(初学者必读)

    Python 是一个解释型语言,可读性与易用性让它越来越热门. 正如 Python 之禅中所述:优美胜于丑陋,明了胜于晦涩. 在你的日常编码中,以下技巧可以给你带来意想不到的收获: 1.字符串反转 下 ...

  6. 周五话营销 | 健身房花式卖卡,诠释点击营销流

    公司楼下近期新开了一个健身房, 广告轰炸老烦了, Tony.Jack 和 Tom 轮番给我塞传单,然后全部丢掉, 终于有一天我遇到了自己的 Mr.Right--王小明, 所以我还是被套路了,办了一张年 ...

  7. HR赫莲娜携张雨绮、胡杏儿、杨丞琳等先锋女性诠释改变

    上海2021年8月10日 /美通社/ -- HR赫莲娜始终坚信"改变·自有力量",每位女性与生俱来便内蕴力量.所以赫莲娜致力于鼓舞每一个时代的女性不为自我设限,更赋能女性由内而外地 ...

  8. 你就是光!王思琴老师加冕2022第三季完美大师全球人气季军!

    星光璀璨,榜样诞生.在2022第三季完美大师师资盛典的颁奖典礼上,来自完美大师舞台的少儿模特老师--王思琴,在完美大师的竞演舞台上夺得完美大师全球人气季军的荣誉殊荣.她就像是一道曙光,在师资盛典的舞台 ...

  9. SDN和Openflow flowvisor NOX

    目录(?)[-] 简介 编辑本段传统路由器的设计 设计思想 虚拟化的逆袭网络虚拟化之OpenFlow和SDN Open还是Flow OpenFlow对产业链的影响 OpenFlow面临的技术难点 结论 ...

最新文章

  1. oracle个性化,Oracle:个性化营销成功的五细则
  2. linux socket 缓冲区默认大小
  3. 每个程序员都必须遵守的编程原则
  4. RPC与其实现方式概念笔记
  5. intellij工程文件名都是红色+右键没有run选项
  6. 计算机技术qq交流群,专业计算机群QQ
  7. nodejs的内存管理,垃圾回收机制
  8. Solidworks如何将参考平面的图形投影到某曲面上
  9. fiddler工具条、状态栏、请求信息栏各按钮的作用
  10. 复选框怎么点td选中_jQuery点击tr实现checkbox选中的方法
  11. 趣挨踢 | 阿里员工吐槽:我在阿里工作五年,面试一个小公司竟然挂了
  12. input radio 样式
  13. wireshark数据包分析实战 第三、四章
  14. 小学计算机课程报告怎么写,小学计算机课论文摘要怎么写 小学计算机课论文摘要范文参考...
  15. Linq to sql(六):探究特性(四)
  16. 指针数组 | 数组指针
  17. 用java画工作流流程图,java生成流程图
  18. 网站去除plugin.php小尾巴,dedecms去除首页index.html小尾巴,这种方法是错误的!
  19. GStreamer播放教程05——色彩平衡
  20. 关于QPainter无法绘制问题

热门文章

  1. oppo小游戏接入代码
  2. 苹果使用过程中的小技巧(合集)
  3. win7系统服务print spooler 无法启动解决方法(开启及关闭方法)
  4. 弹性云服务器---ECS
  5. Liunx系统格式化磁盘和挂载备份盘
  6. 为什么你需要一台NAS(网盘云盘vs路由器硬盘vsNAS)
  7. 远程计算机桌面登录拒绝访问,win7远程界面显示拒绝访问
  8. [CVPR2021-oral]Learning to Aggregate and Personalize 3D Face from In-the-Wild Photo Collection
  9. Matlab学习日记(5)二维曲线的绘制(plot与fplot)
  10. 首席新媒体黎想教程:活动形式和用户吸引逻辑!