C++之虚函数是如何实现的

最近面试过程中问到了虚函数的实现,当时答对了一部分,现在做一个详细的分析:


1.什么是虚函数

在某基类中声明为 virtual 并在一个或多个派生类中被重新定 义的成员函数,用法格式为:virtual 函数返回类型 函数名(参数表) {函数体};,实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数

2.实现多肽的条件

简单的说就是:基类的指针或引用指向子类对象,当子类中成员函数和基类成员函数:函数名相同,参数列表相同,返回值相同,并且基类该函数为虚函数时,基类指针调用该函数时是调用的子类的该函数。

3.虚函数表

C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数。

这里我们着重看一下这张虚函数表。C++的编译器应该是保证虚函数表的指针存在于对象实例中最前面的位置(这是为了保证取到虚函数表的有最高的性能——如果有多层继承或是多重继承的情况下)。 这意味着我们通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。

 

覆盖父类的虚函数是很显然的事情,不然,虚函数就变得毫无意义。下面,我们来看一下,如果子类中有虚函数重载了父类的虚函数,会是一个什么样子?假设,我们有下面这样的一个继承关系。

class Base

{

public:

virtual void f(){}

virual void g(){} 

virtual void h(){} 

}

class Derive : public Base

{

public:

virtual void f(){}

virtual void g1(){}

virtual void h1(){}

} 

 

为了让大家看到被继承过后的效果,在这个类的设计中,我只覆盖了父类的一个函数:f()。那么,对于派生类的实例,其虚函数表会是下面的一个样子:

Derive::f  

Base::g

Base::h

Derive::g1

Derive::h1

 

我们从表中可以看到下面几点,

 

1)覆盖的f()函数被放到了虚表中原来父类虚函数的位置。

 

2)没有被覆盖的函数依旧。

 

这样,我们就可以看到对于下面这样的程序,

 

            Base *b = new Derive();

 

            b->f();

 

b所指的内存中的虚函数表的f()的位置已经被Derive::f()函数地址所取代,于是在实际调用发生时,是Derive::f()被调用了。这就实现了多态。

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

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

相关文章

腾达fh307没有显示服务器名,腾达(Tenda)FH307路由器上网设置 | 192路由网

本文介绍了腾达(Tenda)FH307路由器的安装、上网设置方法,同时分别介绍了“ADSL(PPPOE)拨号”、“动态IP”、“静态IP”三种上网方式的区别,以及在腾达(Tenda)FH307路由器上的详细设置。腾达(Tenda)FH307无线路由器一台新购买的腾达FH307路由器实现上网&a…

记得重用layout

2019独角兽企业重金招聘Python工程师标准>>> 这样的布局&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android" android:layout_width"…

sql2000-2 4/19

SQL2000客戶的上次問題後來H盤自動毀掉了昨天換了顆新硬碟,當資料庫挂上之後,H一直又提示錯誤,後來還是將資料庫路徑設為I傍晚時分親眼目睹了H所有資料被自動刪除的過程,待服務器重新啟動後H無法存取萬幸的是早一步將資料庫路徑作了更動在還原資料庫的過程中用克隆的BAK還原一直…

五一加班

前几年五一放假&#xff0c;我们会去小云家&#xff0c;五一也是荔枝成熟的时候&#xff0c;有一年吃上刚从树上摘的荔枝&#xff0c;现在还能记起那种味道&#xff0c;也是那次之后&#xff0c;想奢入简很难了&#xff0c;荔枝也一定要吃新鲜的了。今年一直还没看到荔枝的影子…

win10系统能做域服务器吗,Win10 LTSC 加入 Windows Server 2019 域服务器

前面的文章已经创建了域服务器、创建了域组织单位、用户组、用户&#xff0c;下面是如何把一台 Win10 LTSC 系统的电脑加入到Windows Server 2019 域服务器&#xff1b;0x01 加域准备修改计算机名、修改IP地址DNS指向 Windows Server 2019 域控制器&#xff1b;注意&#xff1a…

多线程死锁及解决办法

死锁是由于不同线程按照不同顺序进行加锁而造成的。如&#xff1a; 线程A&#xff1a;对lock a加锁 > 对lock b加锁 > dosth > 释放lock b > 释放lock a 线程B&#xff1a;对lock b加锁 > 对lock a加锁 > dosth > 释放lock a > 释放lock b 这样两条线程…

html:web前端开发规范

基本原则* 遵循内容&#xff08;HTML&#xff09;、显示&#xff08;CSS&#xff09;、行为&#xff08;JavaScript&#xff09;分离的代码组织模式 * 代码格式化&#xff0c;保持干净整洁 HTML部分2.1. 添加必须的utf-8的字符集&#xff0c;并且使用HTML5的简洁方式&#xff1…

离职就打低绩效,这样对吗?

应该不止听见一个人说过&#xff0c;担心离职遇到各种不爽的事情&#xff0c;比如卡你的离职时间&#xff0c;比如让你背很低的绩效&#xff0c;比如你今年的年终奖就没有了&#xff0c;再比如&#xff0c;你和原来玩得好的同事突然就没话说了。我记得很清楚的事情是&#xff0…

+ 网页制作效果常用代码

控制横向和纵向滚动条的显隐&#xff1f;<body style"overflow-y:hidden"> 去掉x轴<body style"overflow-x:hidden"> 去掉y轴<body scroll"no">不显表格变色<TD οnmοuseοver"this.style.backgroundColor#FFFFFF&qu…

设计一个串口服务器设备.《需求分析报告》,《项目开发,分布式多串口交换服务器的设计与实现...

摘要&#xff1a;随着信息技术和物联网技术的迅猛发展,TCP/IP网络应用呈现白热化趋势,各种以TCP/IP网络为主的通信设备已经成为主流,网络似乎无处不在.这种局面使得传统的以串行通信为主要通信方式的设备逐渐边缘化,然而要全部更换串行设备,成本开销太大,分布式多串口交换服务器…

设计模式的理解的总结

参考的博客&#xff1a;http://blog.csdn.net/wangeen/article/details/8272501 最近又把设计模式翻了一边&#xff0c;写个个人总结&#xff0c;这个总结比较简单&#xff0c;主要是一些理解&#xff0c;对于他们的实现和应用以后再总结 设计模式是编程抽象化的一个具体的应用…

PID算法原理介绍

先来彻底搞懂PID到底是啥&#xff1f;PID&#xff0c;就是“比例&#xff08;proportional&#xff09;、积分&#xff08;integral&#xff09;、微分&#xff08;differential&#xff09;”&#xff0c;是一种很常见的控制算法。在工程实际中&#xff0c;应用最为广泛的调节…

将python代码编译成.so文件

https://moonlet.gitbooks.io/cython-document-zh_cn/content/ch1-basic_tutorial.html add_num.pyx文件 def add_nums(ls):total 0.for l in ls:total lreturn totalset_up.py from distutils.core import setup from Cython.Build import cythonizesetup(ext_modules cyth…

将iphone中的照片同步到电脑

在windows中&#xff1a; 去我的电脑&#xff0c;点iphone的图标&#xff0c;打开直接就是照片的文件夹&#xff0c;可以进行各种操作&#xff1b; 在mac中&#xff1a; 使用iphoto软件&#xff0c;选择iphoto的菜单栏中“iphoto”->"performance"->"gene…

雅虎公司C#笔试题

雅虎公司C#笔试题&#xff0c;包括问答题和选择题两部分。试试看&#xff0c;你能回答出多少题&#xff0c;可以通过雅虎的考试吗&#xff1f;Question 1. (单选)在计算机网络中,表征数据传输可靠性的指标是1. 传输率2. 误码率3. 信息容量4. 频带利用率Question 2. (单选)以下关…

打败opencv ,哦,是快了3倍

大家好&#xff0c;本文转自我一个读者朋友Homio的文章&#xff0c;推荐给大家&#xff0c;希望对做这方便的同学有所帮助。程序员&#xff0c;哦&#xff01;不&#xff01;软件工程师们都对opencv很熟悉&#xff0c;它在工作学习研究中起到了不可或缺的作用。但是它臃肿的身躯…

Linux内核裁减

Linux内核裁减 &#xff08;1&#xff09;安装新内核: i)将新内核copy到/usr/src下, #tar xzvf linux-2.6.38.4.tar.gz -----解压缩. ii) 将名为linux的符号链接删掉,这是旧版本内核的符号链接. #ln -s linux-2.6.38.4 linux ------建立linux-2.6.38.4的符号链接linux. &#x…

python 将一个字符list的列表扁平化成了一个list

a[[app,ap,ade],[er],[bcc,brt]] 将这么一个list 转换成 a2[app,ap,ade,er,bcc,brt] 做法&#xff1a;a2[x for tup in a for x in tup] 转载于:https://www.cnblogs.com/cheng-cheng/p/10027446.html

数据库中使用自增量字段与Guid字段作主键的性能对比(补充篇)-----转

我在发表过“据库中使用自增量字段与Guid字段主键的性能对比”这篇文章后&#xff0c;得到博客园各园友的很多评价&#xff0c;大家对我的测试方法也提出一些改进的方法。让我吃惊的是一园友提出&#xff1a;把guid和id的测试顺序颠倒一下&#xff0c;看下结果。今天就再测试一…

JDBC操作数据库就这八步!

1.載入JDBC驅動程式 內含於JDK中&#xff0c;名稱為"Sun.jdbc.odbc.JdbcOdbcDriver"&#xff0c;可以使用"java.lang"套件下的 Class.forName()方法載入。 2.透過DriverManager類別建立Connection物件 於"java.sql"套件下可以運用到此JDBC API&a…