C++中为什么要用虚函数、指针或引用才能实现多态?
发布日期:2022-02-10 13:35:52 浏览次数:38 分类:技术文章

本文共 1290 字,大约阅读时间需要 4 分钟。

学过C++的都知道,要实现C++的多态性必须要用到虚函数,并且还要使用引用或者指针,以前学习的时候书本上也是这么说,

但是书本上没有说为什么?   其实只要你认真思考过这个问题你会有三个疑问:

为什么要用虚函数?

为什么要用指针或者引用?

为什么使用派生类和基类对象之间直接赋值不能实现??

一个简单的例子:

class A{public:    virtual void print()    {cout<<"A"<
print(); a = b; //不能实现多态,为什么? a.print(); return 0;}

进一步的,了解C++的人都应该知道只要有虚函数的类就会有一张虚函数表,多态就是通过这张表来实现的。

所以,只要你不断探索下去,就会很快发现前面两个疑问豁然开朗,在这里,我主要探索第三个疑问。

好了,我这里假设你已经对前面两个问题很清楚了。我们进一步把这个问题细化:

程序执行a = b操作时,b中的虚表到底有没有赋给a?

若赋给a了,是不是一定要用指针或引用才能通过虚表调用虚函数?

下面我们通过一个小程序,探索一下:

class A	{	public:     virtual void T(){}	    virtual void print()	    {cout<<"A"<

首先我们通过调试来看看虚函数表:

程序运行到a=b处时:

我们可以看到B类(派生类)如果覆盖了A类(被继承类)的成员函数,则B类(派生类)的虚函数表第二项(*vtptr[1])的内容也会被覆盖,但是A类(被继承类)的虚函数表的其他表项依然被继承过来,表项的顺序和他们在A类(被继承类)的声明是一致(在这里我不再验证)。

程序运行到a.print()处时:

我们可以看到A类(被继承类)中的虚函数表项并没有被覆盖,也就说没有赋值过来,所以自然的使用a.print()时,也只是调用自己的成员函数。

到这里我们找到了第一个疑问的答案。

既然默认的赋值运算没有实现虚表的赋值,那么我们就重写A类的成员函数operaotor =:

A& operator = (const B& b)    {        *(int *)this=*(int *)&b;        return *this;    }
添加了代码之后,我们继续来运行上面的代码,得到如图的运行结果:

这说明,对象去访问成员的虚函数并不通过虚函数表。

为了验证虚函数表的确传了过去,可以再添加下面两行代码:

A *pa = &a;pa->print();
输出如下:

到这里为止,提出的疑问基本上已经有了答案。但是,又产生了新的疑问,对象为什么访问不了虚函数表?

一句话解释:

1.默认的赋值运算符并不会操作虚函数表。

2.要实现多态,必须使用指针或者引用。

后话:文章到此结束,对于后面那个疑问,博主我也不知道答案,如果你知道,麻烦留言告知一下,还有就是此文我只是想记录一下我探索的过程,其中可能会有错误,所以如果你发现了错误,请你一定要提出来,以免我误导其他读者,谢谢!

转载地址:https://blog.csdn.net/zoopang/article/details/14071779 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:力扣字符串17题电话号码的字母组合
下一篇:适配器模式

发表评论

最新留言

不错!
[***.144.177.141]2024年03月20日 19时40分24秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

android 智能手环应用,戴图智能手环app(健康手环应用) 1.7.8安卓版 2019-04-21
vue router 原生html,vue-router的HTML5 History 模式设置 2019-04-21
android cs框架,Android UI 框架 Lattekit 2019-04-21
html的后代选择器,html5怎么使用后代选择器?html选择后代的两种方式详解! 2019-04-21
C# html日期选择控件,C# 解决TextBox中, JS方法(日历)改变Text内容后, 无法触发OnTextChanged事件的问题————详细教程(你就说优秀不)... 2019-04-21
ef html页面时间布局,MVC+EF 随笔小计——分部视图(Partial View)及Html.Partial和Html.Action差异... 2019-04-21
html5数据推送应用开发 代码,HTML5数据推送应用开发 2019-04-21
html输入框组摁钮组,bootstrap 通过加减按钮实现输入框组功能 2019-04-21
html中repeat平铺图片5张,no-repeat 2019-04-21
ai旋转扭曲_AI变换及旋转图形工具详解 2019-04-21
3t硬盘 xp_怎么让xp支持3T硬盘 2019-04-21
python的web抓取_带有请求的Python Web抓取-登录后 2019-04-21
kswapd0 挖矿_Linux kswapd0 进程CPU占用过高 2019-04-21
opengl绘制长方体线框_OpenGL 绘制应用纹理的矩形 2019-04-21
c-free显示运行程序错误怎么办_电脑蓝屏了怎么办?小白看这里! 2019-04-21
aop的实现原理_你必须要懂的 Spring:Aop 2019-04-21
4位先行进位电路 logisim_数字电路学习笔记(八):计算电路 2019-04-21
spyder怎么看已有的包_怎么样做一份好吃的羊肉手抓饭?看了包学会 2019-04-21
freebuds3怎么查激活日期_怎么查股票的月平均价格 中泰证券股票上市日期 2019-04-21
八类网线和七类网线的区别_七类网线的知识你知道多少? 2019-04-21