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

多态基础

多态的实现效果

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

多态实现的三个条件

有继承、有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. Web前端开发——HTML基本标签

    标题h1-h6 只有h1到h6,没有h7. 一个页面建议只有一个h1 普通文字大小大约介于h3~h4 段落p 段内换行br 段内分组span 预留格式pre 水平线hr

  2. 『NOIP 2019Day2 T3』 保卫王国(defense)

    重温NOIP2018的试题,发现只要好好想想还是能想出一些东西的. 比如说本题是一个DDP的模板题,硬是做成了倍增优化DP的题目. 对于给出的$n$个节点的树,每个点都有点权$v_i$,共$Q$次询问 ...

  3. 灰度图像--图像分割 Scharr算子

    学习DIP第46天 转载请标明本文出处:http://blog.csdn.net/tonyshengtan ,出于尊重文章作者的劳动,转载请标明出处!文章代码已托管,欢迎共同开发: https://g ...

  4. canvas小实验

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. python用BeautifulSoup解析源码时,去除空格及换行符

    一.去除空格 strip()   " xyz ".strip() # returns "xyz"   " xyz ".lstrip() # ...

  6. css基础(css书写 背景设置 标签分类 css特性)

      css书写位置   行内式写法 <p style="color:red;" font-size:12px;></p> 外联式写法 <link re ...

  7. flask入门第一篇

    一. Python 现阶段三大主流Web框架 Django Tornado Flask 对比 1.Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form 等等, 不 ...

  8. 09.变态跳台阶 Java

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 思路 0:0 1:(1) 2:(1,1)(2) 3:(1,1,1)(2,1)( ...

  9. 安装ubuntu是所需的引导

    title Install Ubuntu root (hd0,0) kernel (hd0,0)/vmlinuz boot=casper iso-scan/filename=/ubuntu-16.04 ...

  10. anaconda环境管理

    创建新环境 conda create -n rcnn python=3.6 删除环境 conda remove -n rcnn --all 重命名环境 参考SO:https://stackoverfl ...