深入了解多态的实现原理,有助于提高对于多态的认识

多态基础

多态的实现效果

多态:同样的调用语句有多种不同的表现形态

多态实现的三个条件

有继承、有virtual重写、有父类指针(引用)指向子类对象

多态的C++实现

virtual关键字,告诉编译器这个函数要支持多态;不要根据指针类型判断如何调用;而是要根据指针所指向的实际对象类型来判断如何调用

多态的理论基础

动态联编PK静态联编。根据实际的对象类型来判断重写函数的调用

多态的重要意义

设计模式的基础

实现多态的理论基础

函数指针做函数参数

C++中多态的实现原理

  • 当类中声明虚函数时,编译器会在类中生成一个虚函数表
  • 虚函数表是一个存储类成员函数指针的数据结构
  • 虚函数表是由编译器自动生成与维护的
  • virtual成员函数会被编译器放入虚函数表中
  • 存在虚函数时,每个对象中都有一个指向虚函数表的指针(vptr指针)





    说明:
  • 通过虚函数表指针VPTR调用重写函数是在程序运行时进行的,因此需要通过寻址操作才能确定真正应该调用的函数。而普通成员函数是在编译时就确定了调用的函数。在效率上,虚函数的效率要低很多。
  • 出于效率考虑,没有必要将所有成员函数都声明为虚函数

关于多态的一些问题

多态是怎么一步步实现的?

  1. 使用virtual关键字时候,生成虚函数表
  2. 在函数调用时候判断是子类还是父类
  3. 调用相应的方法

对象中的VPTR指针什么时候被初始化?

对象在创建的时,由编译器对VPTR指针进行初始化

只有当对象的构造完全结束后VPTR的指向才最终确定

父类对象的VPTR指向父类虚函数表

子类对象的VPTR指向子类虚函数表

分析过程

构造函数中调用多态函数,不能实现多态

主要原因是:在构造函数调用的时候还没完成初始化

此时虚函数尚未指向完成

完成父类构造函数初始化才对vptr进行指向

如何证明vptr指针的存在哪?

class AA
{
public:
virtual void print()
{
printf("test\n");
}
protected:
private:
int b;
};

当存在virtual关键字时,sizeof(AA)得到8,而当此关键字不在的时候,得到4。这4个字节的内存空间装的就是这个函数指针

C++学习笔记-多态的实现原理的更多相关文章

  1. Java IO学习笔记:概念与原理

    Java IO学习笔记:概念与原理   一.概念   Java中对文件的操作是以流的方式进行的.流是Java内存中的一组有序数据序列.Java将数据从源(文件.内存.键盘.网络)读入到内存 中,形成了 ...

  2. tensorflow学习笔记——模型持久化的原理,将CKPT转为pb文件,使用pb模型预测

    由题目就可以看出,本节内容分为三部分,第一部分就是如何将训练好的模型持久化,并学习模型持久化的原理,第二部分就是如何将CKPT转化为pb文件,第三部分就是如何使用pb模型进行预测. 一,模型持久化 为 ...

  3. 强化学习-学习笔记7 | Sarsa算法原理与推导

    Sarsa算法 是 TD算法的一种,之前没有严谨推导过 TD 算法,这一篇就来从数学的角度推导一下 Sarsa 算法.注意,这部分属于 TD算法的延申. 7. Sarsa算法 7.1 推导 TD ta ...

  4. 机器学习实战(Machine Learning in Action)学习笔记————10.奇异值分解(SVD)原理、基于协同过滤的推荐引擎、数据降维

    关键字:SVD.奇异值分解.降维.基于协同过滤的推荐引擎作者:米仓山下时间:2018-11-3机器学习实战(Machine Learning in Action,@author: Peter Harr ...

  5. Android(java)学习笔记95:Android原理揭秘系列之View、ViewGroup

    作过Android 应用开发的朋友都知道,Android的UI界面都是由View和ViewGroup及其派生类组合而成的.其中,View是所有UI组件的基类,而ViewGroup是容纳这些组件的容器, ...

  6. Android(java)学习笔记34:Android原理揭秘系列之View、ViewGroup

    1. 作过Android 应用开发的朋友都知道,Android的UI界面都是由View和ViewGroup及其派生类组合而成的.其中,View是所有UI组件的基类,而ViewGroup是容纳这些组件的 ...

  7. C++学习笔记-多态

    多态作为面向对象的重要概念,在如何一门面向对象编程语言中都有着举足轻重的作用,学习多态,有助于更好地理多态的行为 多态性(Polymorphism)是指一个名字,多种语义:或界面相同,多种实现. 重载 ...

  8. [spring入门学习笔记][spring的IoC原理]

    什么叫IoC 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中最常见的方式叫做依赖注入(Dependency ...

  9. Struts2 学习笔记18 拦截器原理分析

    我们来进行一下拦截器的原理分析,从Struts2的源代码开始,然后我们手动创建一个项目进行模拟.(源代码需要下载然后添加好才能看到)我们可以用Debug来读源码. 从doFilter开始执行,流程如图 ...

随机推荐

  1. Canvas实用库Fabric.js使用手册

    简介什么是Fabric.js? Fabric.js是一个可以简化Canvas程序编写的库. Fabric.js为Canvas提供所缺少的对象模型, svg parser, 交互和一整套其他不可或缺的工 ...

  2. html 与 jsp 文件格式区别

    html 与 jsp 文件格式区别 html5 <!DOCTYPE html> <html> <head> <meta charset="UTF-8 ...

  3. 使用CSS3 will-change提高页面滚动、动画等渲染性能----------------------------引用

    Chris Ruppel当其使用background-attachment: fixed实现背景图片不随滚动条滚动而滚动效果的时候, 大家肯定会好奇,这到底施了什么魔法,可以让渲染提升如此之显著.3个 ...

  4. 什么是favicon.ico?

    ㈠定义 ⑴所谓favicon,即Favorites Icon的缩写,顾名思义,便是其可以让浏览器的收藏夹中除显示相应的标题外,还以图标的方式区别不同的网站. ⑵根据浏览器的不同,Favicon显示也有 ...

  5. jquery blur()函数 语法

    jquery blur()函数 语法 作用:当元素失去焦点时发生 blur 事件.blur() 函数触发 blur 事件,或者如果设置了 function 参数,该函数也可规定当发生 blur 事件时 ...

  6. 在Ubuntu 18.04系统中蓝牙鼠标连接失败问题的解决

    2018-08-22 16:00:35作者:谖瓞稿源:linux站 如果你在Ubuntu 18.04操作系统中有蓝牙鼠标连接失败问题,那就参考下面的解决方法处理. 解决方法 首先在系统终端下输入: b ...

  7. Confluence 6 删除一个附加的文件

    你需要具有 删除附件(Delete Attachment)的空间权限来删除一个附加的文件. 希望删除一个附加文件的所有版本: 进入含有附件的页面中. Go to  > Attachments 选 ...

  8. noi.ac #534 猫

    题目链接:戳我 [问题描述] 有n座山,m只猫和p个工作人员.山从左往右编号为1∼n,山i和i−1之间的距离是di米. 有一天,猫都到山上去玩了:第i只猫会到山hi去,并一直玩到时间ti,之后就在那座 ...

  9. MySQL_(Java)【连接池】简单在JDBCUtils.java中创建连接池

    MySQL_(Java)[事物操作]使用JDBC模拟银行转账向数据库发起修改请求 传送门 MySQL_(Java)[连接池]使用DBCP简单模拟银行转账事物 传送门 Java应用程序访问数据库的过程: ...

  10. 一个服务器的Apache2.4.6配置多个域名

    进入到Apache的配置文件:cd /etc/httpd/conf/http.conf 在后面添加: <VirtualHost *:80> # This first-listed virt ...