C++面向对象总结:虚指针与虚函数表,干货又来了

时间:2022-10-09 17:50:47 | 浏览:295

最近在逛B站的时候发现有候捷老师的课程,如获至宝。因此,跟随他的讲解又复习了一遍关于C++的内容,收获也非常的大,对于某些模糊的概念及遗忘的内容又有了更深的认识。以下内容是关于虚函数表、虚函数指针,而C++中的动态绑定实现和这两个内容是分不

最近在逛B站的时候发现有候捷老师的课程,如获至宝。因此,跟随他的讲解又复习了一遍关于C++的内容,收获也非常的大,对于某些模糊的概念及遗忘的内容又有了更深的认识。

以下内容是关于虚函数表、虚函数指针,而C++中的动态绑定实现和这两个内容是分不开的。

一,虚函数表、虚指针

当一个类在实现的时候,如果存在一个或以上的虚函数时,那么这个类便会包含一张虚函数表。而当一个子类继承并重写了基类的虚函数时,它也会有自己的一张虚函数表。

当我们在设计类的时候,如果把某个函数设置成虚函数时,也就表明我们希望子类在继承的时候能够有自己的实现方式;如果我们明确这个类不会被继承,那么就不应该有虚函数的出现。

下面是某个基类A的实现:

从下图中可以看到该类在内存中的存放形式,对于 虚函数的调用是通过查虚函数表来进行的 ,每个虚函数在虚函数表中都存放着自己的一个地址,而如何在 虚函数表中进行查找,则是通过虚指针来调用 ,在内存结构中它一般都会放在类最开始的地方,而对于普通函数则不需要通过查表操作。这张 虚函数表是 什么时候被创建的呢?它是 在编译的时候产生 ,否则这个类的结构信息中也不会插入虚指针的地址信息。

以下例子包含了继承关系:

以上三个类在内存中的排布关系如下图所示:

对于非虚函数,三个类中虽然都有一个叫 func2 的函数,但他们彼此互不关联,因此都是各自独立的,不存在重载一说,在调用的时候也不需要进行查表的操作,直接调用即可。

由于子类B和子类C都是继承于基类A,因此他们都会存在一个虚指针用于指向虚函数表。注意,假如子类B和子类C中不存在虚函数,那么这时他们将共用基类A的一张虚函数表,在B和C中用虚指针指向该虚函数表即可。但是,上面的代码设计时子类B和子类C中都有一个虚函数 vfunc1 ,因此他们就需要各自产生一张虚函数表,并用各自的虚指针指向该表。由于子类B和子类C都对 vfunc1 作了重载,因此他们有三种不同的实现方式,函数地址也不尽相同,在使用的时候需要从各自类的虚函数表中去查找对应的 vfunc1 地址。

对于虚函数 vfunc2 ,两个子类都没有进行重载操作,所以基类A、子类B和子类C将共用一个 vfunc2 ,该虚函数的地址会分别保存在三个类的虚函数表中,但他们的地址是相同的。

从上图可以发现,在类对象的头部存放着一个虚指针,该虚指针指向了各自类所维护的虚函数表,再通过查找虚函数表中的地址来找到对应的虚函数。

对于类中的数据而言,子类中都会包含父类的信息。如上例中的子类C,它自己拥有一个变量 m_data1 ,似乎是和基类中的 m_data1 重名了,但其实他们并不存在联系,从存放的位置便可知晓。

二,关于动态绑定

首先来说一说静态绑定: 静态绑定是指在 程序编译 过程中,把函数(方法或者过程)调用与响应调用所需的代码结合的过程(如何理解呢?)

来看一段代码:

可以看到调用的却是派生类的函数。

在没有加 virtual 关键字的时候,通过基类指针指向派生类对象时, 基类指针只能访问派生类的成员变量,但是不能访问派生类的成员函数。 这是因此在系统编译过程中,已经将area()函数和shape类绑定在一起了。

而动态绑定是在加了 virtual 关键字以后,派生类中的成员函数在重写的时候会自动生成自己的虚函数表(单独的一个地址),并通过虚指针指向该地址。

即:shape指针->vptr->Rectangle::area()

​通过以上内容,我们可以知道在使用基类指针调用虚函数的时候,它能够根据所指的类对象的不同来正确调用虚函数。而这些能够正常工作,得益于虚指针和虚函数表的引入,使得在程序运行期间能够动态调用函数。

动态绑定有以下三项条件要符合:

使用指针进行调用

指针属于up-cast后的

调用的是虚函数

静态绑定,他们是类对象直接可调用的,而不需要任何查表操作,因此调用的速度也快于虚函数。

写在最后:其实每个人都有自己的选择,学编程,每一种编程语言的存在都有其应用的方向,选择你想从事的方向,去进行合适的选择就对了!对于准备学习编程的小伙伴,如果你想更好的提升你的编程核心能力(内功)不妨从现在开始!

编程学习书籍分享:

编程学习视频分享:

整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

对于C/C++感兴趣可以关注小编在后台私信我:【编程交流】一起来学习哦!可以领取一些C/C++的项目学习视频资料哦!已经设置好了关键词自动回复,自动领取就好了!

相关资讯

Python太低级,我选C++?码农带你揭穿少儿编程的骗局

本内容来源于@什么值得买APP,观点仅代表作者本人 |作者:玩牛牛创作立场声明:由玩牛牛原创,欢迎转载最近在某乎看到一篇文章,大意是海淀妈妈们已经嫌弃 Python 低级,准备让娃直接入门 C++。看得我这个写了 15 年代码的老码农心惊胆

C/C++编程笔记:C语言编程知识要点总结!大一C语言知识点(全)

一、C语言程序的构成与C++、Java相比,C语言其实很简单,但却非常重要。因为它是C++、Java的基础。不把C语言基础打扎实,很难成为程序员高手。1、C语言的结构先通过一个简单的例子,把C语言的基础打牢。C语言的结构要掌握以下几点:(1

数数科技完成C+轮融资,投资方为GGV纪源资本

2022年8月22日,据IT桔子,数数科技于近日完成C+轮融资。本轮融资的投资方为GGV纪源资本,金额为1亿元。企查查信息显示,数数科技创立于2015年,是国内专业的游戏大数据分析服务商。数数科技以“让数据价值触手可及”为使命,聚焦游戏行业

都说C++太难学了!那么C++到底值不值得我们去学呢?

在大多数开发或者准开发人员的认识中,C/C++ 是一门非常难的编程语言,很多人知道它的强大,但因为认为“难”造成的恐惧让很多人放弃。很多人因为大学的原因接触C语言,却也是为了学习其他编程语言而打下基础,至于C++更是不用说,很多人不会去刻意

互联网行业成短视频人才聚集地,C++岗位平均年薪近50万元

记者 | 陈晓珍编辑 | 9月7日,猎聘发布的《短视频领域中高端人才招聘解析》(以下简称“报告”)显示,短视频领域新发职位的招聘年薪呈持续增长态势。2021年1-8月短视频新发职位平均招聘年薪为27.02万元,相比于2020年(21.05万

C++介绍与入门学习

C++是C语言的继承,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计,因而C++就适应

985学校内部疯传,学完C++能做什么?

大家好,我是柠檬哥,专注编程知识分享。欢迎关注@程序员柠檬橙,编程路上不迷路,最近很多同学私信柠檬哥,问到C++的应用方向和工作方向,这就安排。C++和C语言相比于Java和Python,可以说是比较底层的语言。不像Java有GC,在C++

C++这么难,为啥还是那么多人去学?

如果提到一种语言,可能说这辈子都不敢说精通,有相当数量的人辉选择c++,看看大家如何评述c++,用了两年的c++,转学别的语言发现从未有过的轻松感。c++这门语言比较特殊,是大家公认的人类不能精通的一门语言,如果精通了基本确定这人是非人类了

PHP、Java、Python、C、C++这几种编程语言都有什么特点或优点?

一、强类型和弱类型语言:C、 C++、 Java 、Python都是强类型的语言。PHP是弱类型的语言。强类型语言是一种强制类型定义的语言,即一旦某一个变量被定义类型,如果不经强制转换,那么它永远就是该数据类型。而弱类型语言是一种弱类型定义

C、C++、Java、JavaScript、PHP、Python分别用来开发什么?

首先,我们先普及一下编程语言的基础知识。用任何编程语言来开发程序,都是为了让计算机干活,比如编写一篇文章,下载一首MP3等,而计算机干活的CPU只认识机器的指令,所以,尽管不同的编程语言差异极大,最后都得“翻译”成CPU可以执行的机器指令。

友情链接

SEO域名抢注宝宝起名网妈妈知道币圈趵突泉旅游攻略新加坡旅游网正典燕窝番荔枝资讯网斯洛伐克旅游网布加迪威龙超跑阳江新闻网暗杀风暴电影网严浩翔歌迷网速滑谷爱凌瑜伽资讯网博时基金资讯网防城港白浪滩旅游联想电脑评测网北方稀土A股
c语言中文官网-零基础c++从入门到精通pdf、c语言编译器、C/C++开发工具、c语言入门自学零基础、c++入门自学、c/c++软件下载、c语言编程软件、c语言自学免费网站、c语言零基础自学视频教程、c++手机编程软件、c语言入门程序设计、初级编程视频教程、c语言在线编程平台、C语言线上作业网站。
c语言中文官网 chuxinxin.cn ©2022-2028版权所有