C++ STL deque 容器底层实现原理(深度剖析)

点击蓝字

8d57de8571100fcb042fdba1dc109774.png

关注我们

什么是多态,多态有什么用途?

  • 定义:“一个接口,多种方法”,程序在运行时才决定调用的函数。

  • 实现:C++多态性主要是通过虚函数实现的,虚函数允许子类重写override(注意和overload的区别,overload是重载,是允许同名函数的表现,这些函数参数列表/类型不同)。

  • 目的:接口重用。封装可以使得代码模块化,继承可以扩展已存在的代码,他们的目的都是为了代码重用。而多态的目的则是为了接口重用。

  • 用法:声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。

关于重载、重写的区别

Overload(重载):在C++程序中,可以将语义、功能相似的几个函数用同一个名字表示,但参数或返回值不同(包括类型、顺序不同),即函数重载。
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
Override(重写):是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
注:重写基类虚函数的时候,会自动转换这个函数为virtual函数,不管有没有加virtual,因此重写的时候不加virtual也是可以的,不过为了易读性,还是加上比较好。

虚函数表

多态是由虚函数实现的,而虚函数主要是通过虚函数表(V-Table)来实现的。

如果一个类中包含虚函数(virtual修饰的函数),那么这个类就会包含一张虚函数表,虚函数表存储的每一项是一个虚函数的地址。如下图:

fbe4c7e99ff69b1f25463440dae3f3d3.png

这个类的每一个对象都会包含一个虚指针(虚指针存在于对象实例地址的最前面,保证虚函数表有最高的性能),这个虚指针指向虚函数表

注:对象不包含虚函数表,只有虚指针,类才包含虚函数表,派生类会生成一个兼容基类的虚函数表。

  • 原始基类的虚函数表

下图是原始基类的对象,可以看到虚指针在地址的最前面,指向基类的虚函数表(假设基类定义了3个虚函数)

878740d7de1c245fe0494069ba1ebcbc.png

  • 单继承时的虚函数(无重写基类虚函数)

假设现在派生类继承基类,并且重新定义了3个虚函数,派生类会自己产生一个兼容基类虚函数表的属于自己的虚函数表。

e261d19ccc36893e851d43acb66fcc32.png

Derive class 继承了 Base class 中的三个虚函数,准确的说,是该函数实体的地址被拷贝到 Derive类的虚函数表,派生类新增的虚函数置于虚函数表的后面,并按声明顺序存放

  • 单继承时的虚函数(重写基类虚函数)

现在派生类重写基类的x函数,可以看到这个派生类构建自己的虚函数表的时候,修改了base::x()这一项,指向了自己的虚函数。

3cc33e08253cd86891be7a650c19e75e.png

  • 多重继承时的虚函数(Derived ::public Base1,public Base2)

这个派生类多重继承了两个基类base1,base2,因此它有两个虚函数表。

  e3d3221a24a59967d39fab13f393daeb.png

它的对象会有多个虚指针(据说和编译器相关),指向不同的虚函数表。

*声明:本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

1e820b373bee8e8f6afcee43a3f319ab.png

ae1a071ef809b7bbaab45d302043dc1c.gif

戳“阅读原文”我们一起进步

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

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

相关文章

​常问的16个C语言问题,你能答上来几个?

点击蓝字关注我们最近不少小伙伴在找工作,这里我给大家分享一下面试中经常会遇到的一些嵌入式C语言问题,你看看能答上来几个呢?1用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)#de…

centos linux 内核升级,Centos系统的升级及Linux 内核升级

系统及内核版本:[rootnode5 ~]# cat /etc/redhat-releaseCentOS Linux release 7.3.1611 (Core)[rootnode5 ~]# uname -aLinux node6 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux更新仓库:[rootnode5 yu…

spring javaee_JavaEE还是Spring? 都不行! 我们呼吁新的竞争者!

spring javaee如果您一直在Twitter上关注一些Java的重要人物,或者在Reddit上阅读了“新闻”,那么您一定不会错过Spring和JavaEE宣传人员之间热闹的“贱人之战”(请原谅我的法语)。 首先,于尔根霍勒(JrgenH…

C语言代码优化的方法

点击蓝字关注我们在本篇文章中,我(指原作者)收集了很多经验和方法。应用这些经验和方法,可以帮助我们从执行速度和内存使用等方面来优化C语言代码。简介在最近的一个项目中,我们需要开发一个运行在移动设备上但不保证图像高质量的轻量级JPEG库…

linux源码安装apache2,CentOS7编译安装Apache2

在LAMP环境下对于服务的安装是必不可少的,在linux环境下安装软件也有两种不同的方式,一种是yum安装当然了不同的linux发行版本使用略有不同,另一种是通过编译安装,编译安装要比yum安装要可控此,但是要比yum安装略微麻烦…

C/C++ 命中率比较高的面试知识点,你都答得上来吗

点击蓝字关注我们第一部分:计算机基础1. C/C内存有哪几种类型?C中,内存分为5个区:堆(malloc)、栈(如局部变量、函数参数)、程序代码区(存放二进制代码)、全局/静态存储区(全局变量、static变量&…

svn: 没有演进历程信息_使用默认方法的接口演进–第二部分:接口

svn: 没有演进历程信息引入了默认方法以启用接口演进。 如果向后兼容性是不可替代的,则仅限于向接口添加新方法(这是它们在JDK中的唯一用法)。 但是,如果希望客户端更新其代码,则可以使用默认方法逐步演化接口而不会引…

蓝桥杯7届c语言 c组答案,第七届蓝桥杯C语言C组-(自己懂的题目)

第七届蓝桥杯C语言C组-(自己懂的题目)表示刚刚查了成绩,省赛一等奖,有资格去北京了,然后写一下总结,先来写一下我懂的题目,毕竟我也是菜鸟,听说国赛比预赛难几个等级。。。第一题报纸页数X星球日报和我们地…

关于多线程的几道面试题

点击蓝字关注我们第一题:线程的基本概念、线程的基本状态及状态之间的关系?线程,有时称为轻量级进程,是CPU使用的基本单元;它由线程ID、程序计数器、寄存器集合和堆栈组成。它与属于同一进程的其他线程共享其代码段、数…

大牛谈嵌入式C语言的高级用法

点击蓝字关注我们内存管理我们需要知道——变量,其实是内存地址的一个抽像名字罢了。在静态编译的程序中,所有的变量名都会在编译时被转成内存地址。机器是不知道我们取的名字的,只知道地址。 内存的使用时程序设计中需要考虑的重要因素之一&…

博科光纤交换机java_带有光纤的可扩展,健壮和标准的Java Web服务

博科光纤交换机java这篇博客文章讨论了负载下的基准Web服务性能。 要了解有关Web服务性能理论的更多信息,请阅读利特尔定律,可伸缩性和容错 。 使用阻塞和异步IO对Web服务进行基准测试 Web应用程序(或Web服务)如何在负载下&#…

很棒的C语言入门笔记,推荐收藏!

点击蓝字关注我们c语言入门C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效率高而且可移植性好,可以用来开发应用软件、驱动、操作系统等。C语言也是其它众多高级语言的鼻祖语言,所以说学习…

C语言的注释要注意几点

点击蓝字关注我们如果领导给你一个项目的源码让你阅读,并理解重构代码,但里面一句注释都没有,我想这肯定是之前同事“删库跑路”了。看一份源码什么很重要?除了各种代码规范之外,还有一个比较重要的就是注释。注释虽然…

java自动推断类型_推断:Facebook的新Java静态分析工具

java自动推断类型如何使用Facebook的Infer改善Java开发工作流程? 如果您与技术话题保持同步(如果您正在阅读此博客,我想您会这样做),那么您可能听说过Facebook 刚刚向公众发布的新工具:推断。 由于它来自F…

android官方架构组件,Android 架构组件官方文档01——LifeCycle

使用生命周期感知组件处理生命周期支持生命周期的组件执行操作以响应另一个组件(例如Activity和fragment)的生命周期状态更改。这些组件可帮助您生成组织性更好,并且通常更轻量的代码,这些代码更易于维护。常见的模式是在Activity和fragment的生命周期方…

C语言的核心和灵魂

点击蓝字关注我们提起C语言大部分开发者很自然就会想到指针二字,没错,作为C的核心和灵魂,它的地位咱们就不再赘述了。今天我们想跟大家讲的是指针中的两个特有名词:“悬空指针”和“野指针”。悬空指针C语言中的指针可以指向一块内…

javaone_JavaOne 2015 –提交技巧和建议

javaone大家都知道JavaOne 。 感觉就像一直存在。 而且,即使我们跌宕起伏,而地理位置也不是我们想要的那样,旧金山也很昂贵,而且和。 这是有关各种Java的顶级会议。 今年又再次成为程序委员会(“ Java,DevO…

C语言_结构体总结,附实例源码

点击蓝字关注我们当前文章介绍动态堆空间内存分配与释放,C语言结构体定义、初始化、赋值、结构体数组、结构体指针的相关知识点,最后通过一个学生管理系统综合练习结构体数组的使用。1. 动态内存管理C语言代码----->编译----->链接------>可执行…

四大C语言知识总结

点击蓝字关注我们1、#define宏定义以#号开头的都是编译预处理指令,它们不是C语言的成分,但是C程序离不开它们,#define用来定义一个宏,程序在预处理阶段将用define定义的来内容进行了替换。因此在程序运行时,常量表中并…

jdbc select语句_SELECT语句使用JDBC和Hibernate批量获取

jdbc select语句介绍 现在,我已经介绍了Hibernate对INSERT , UPDATE和DELETE语句的批处理支持,是时候分析SELECT语句结果集的批量提取了。 JDBC ResultSet提供了一个客户端Proxy游标,用于获取当前语句的返回数据。 执行该语句后&…