C++学习笔记-多态的实现原理
深入了解多态的实现原理,有助于提高对于多态的认识
多态基础
多态的实现效果
多态:同样的调用语句有多种不同的表现形态
多态实现的三个条件
有继承、有virtual重写、有父类指针(引用)指向子类对象
多态的C++实现
virtual关键字,告诉编译器这个函数要支持多态;不要根据指针类型判断如何调用;而是要根据指针所指向的实际对象类型来判断如何调用
多态的理论基础
动态联编PK静态联编。根据实际的对象类型来判断重写函数的调用
多态的重要意义
设计模式的基础
实现多态的理论基础
函数指针做函数参数
C++中多态的实现原理
- 当类中声明虚函数时,编译器会在类中生成一个虚函数表
- 虚函数表是一个存储类成员函数指针的数据结构
- 虚函数表是由编译器自动生成与维护的
- virtual成员函数会被编译器放入虚函数表中
- 存在虚函数时,每个对象中都有一个指向虚函数表的指针(vptr指针)



说明: - 通过虚函数表指针VPTR调用重写函数是在程序运行时进行的,因此需要通过寻址操作才能确定真正应该调用的函数。而普通成员函数是在编译时就确定了调用的函数。在效率上,虚函数的效率要低很多。
- 出于效率考虑,没有必要将所有成员函数都声明为虚函数
关于多态的一些问题
多态是怎么一步步实现的?
- 使用virtual关键字时候,生成虚函数表
- 在函数调用时候判断是子类还是父类
- 调用相应的方法
对象中的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++学习笔记-多态的实现原理的更多相关文章
- Java IO学习笔记:概念与原理
Java IO学习笔记:概念与原理 一.概念 Java中对文件的操作是以流的方式进行的.流是Java内存中的一组有序数据序列.Java将数据从源(文件.内存.键盘.网络)读入到内存 中,形成了 ...
- tensorflow学习笔记——模型持久化的原理,将CKPT转为pb文件,使用pb模型预测
由题目就可以看出,本节内容分为三部分,第一部分就是如何将训练好的模型持久化,并学习模型持久化的原理,第二部分就是如何将CKPT转化为pb文件,第三部分就是如何使用pb模型进行预测. 一,模型持久化 为 ...
- 强化学习-学习笔记7 | Sarsa算法原理与推导
Sarsa算法 是 TD算法的一种,之前没有严谨推导过 TD 算法,这一篇就来从数学的角度推导一下 Sarsa 算法.注意,这部分属于 TD算法的延申. 7. Sarsa算法 7.1 推导 TD ta ...
- 机器学习实战(Machine Learning in Action)学习笔记————10.奇异值分解(SVD)原理、基于协同过滤的推荐引擎、数据降维
关键字:SVD.奇异值分解.降维.基于协同过滤的推荐引擎作者:米仓山下时间:2018-11-3机器学习实战(Machine Learning in Action,@author: Peter Harr ...
- Android(java)学习笔记95:Android原理揭秘系列之View、ViewGroup
作过Android 应用开发的朋友都知道,Android的UI界面都是由View和ViewGroup及其派生类组合而成的.其中,View是所有UI组件的基类,而ViewGroup是容纳这些组件的容器, ...
- Android(java)学习笔记34:Android原理揭秘系列之View、ViewGroup
1. 作过Android 应用开发的朋友都知道,Android的UI界面都是由View和ViewGroup及其派生类组合而成的.其中,View是所有UI组件的基类,而ViewGroup是容纳这些组件的 ...
- C++学习笔记-多态
多态作为面向对象的重要概念,在如何一门面向对象编程语言中都有着举足轻重的作用,学习多态,有助于更好地理多态的行为 多态性(Polymorphism)是指一个名字,多种语义:或界面相同,多种实现. 重载 ...
- [spring入门学习笔记][spring的IoC原理]
什么叫IoC 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中最常见的方式叫做依赖注入(Dependency ...
- Struts2 学习笔记18 拦截器原理分析
我们来进行一下拦截器的原理分析,从Struts2的源代码开始,然后我们手动创建一个项目进行模拟.(源代码需要下载然后添加好才能看到)我们可以用Debug来读源码. 从doFilter开始执行,流程如图 ...
随机推荐
- buuctf@ciscn_2019_n_1
from pwn import * #io=process('./ciscn_2019_n_1') io=remote('node3.buuoj.cn',28216) io.sendline(0x38 ...
- 基于node.js的websocket 前后端交互小功能
一.node var ws = require("nodejs-websocket"); console.log("开始建立连接...") var server ...
- js上传超大文件解决方案
需求: 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验: 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包 ...
- delphi请求http接口并上传附件
实现附件的上传:需要使用TIdMultiPartFormDataStream控件, uses IdMultipartFormData; 例子: procedure TClientForm.Button ...
- 关于MapReduce的测试
题目:数据清洗以及结果展示 要求: Result文件数据说明: Ip:106.39.41.166,(城市) Date:10/Nov/2016:00:01:02 +0800,(日期) Day:10,(天 ...
- JAVA常见工具配置
1.MyEclipse中配备struts.xml的自动提示 https://jingyan.baidu.com/article/9158e0004054baa2541228e2.html 2.MySQ ...
- Python 之 subprocess模块
一.subprocess以及常用的封装函数运行python的时候,我们都是在创建并运行一个进程.像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序.在Python ...
- koa 基础(二十五)数据库 与 art-template 模板 联动 --- 新增数据
1.视图层 根目录/views/index.html <!DOCTYPE html> <html lang="en"> <head> <m ...
- android data binding jetpack VI 清理一些概念。BR 运算表达式
android data binding jetpack VIII BindingConversion android data binding jetpack VII @BindingAdapter ...
- Java静态函数、父类、子类执行顺序
package class_test; /** * 静态函数.父类.子类执行顺序 * @author root * */ public class Test { public static void ...