C++多态及其实现原理
1. 多态的定义:多态含义为一个事物有多种形态。在C ++程序设计中,多态性是指具有不同功能的函数可以用同一个函数名,这样就可以用一个函数名调用不同内容的函数,主要分为静态多态和动态多态;
静态多态:就是重载,因为在编译期决议确定,所以称为静态多态。在编译时就可以确定函数地址。
动态多态:就是通过继承重写基类的虚函数实现的多态,因为是在运行时确定决议,所以称为动态多态。运行时在虚函数表中寻找调用函数的地址。
2. 多态的现象:当子类中重写了父类的虚函数,那么通过父类的指针或者引用指向父类对象或着子类对象;用该父类指针或者引用调用父子中被重写的函数;就会有父类指针指向父类对象,调用的是父类中的虚函数;父类指针指向的是子类对象,调用的是子类虚函数;此时,也符合赋值兼容规则;不贵父类的指针或者引用指向父类对象或者子类对象;这个父类指针或者引用都只能访问父类的部分。
3. 动态多态原理:动态多态依靠运行时的类型检查来进行函数的迟绑定。声明一个类时,如果类中有虚方法,则自动在类中增加一个虚函数指针,该指针指向的是一个虚函数表,虚函数表中存着每个虚函数真正对应的函数地址。动态多态采用一种延迟绑定技术,普通的函数调用,在编译期间就已经确定了调用的函数的地址,所以无论怎样调用,总是那个函数,但是拥有虚函数的类,在调用虚函数时,首先去查虚函数表,然后再确定调用的是哪一个函数,所以,调用的函数是在运行时才会确定的。
· 当指向父类的对象时,由于本身是父类指针;且父类对象模型中的虚函数表指针所指向的虚函数表中只存放父类的虚函数地址;所以父类的指针调用的重写虚函数时父类的虚函数;
· 当父类指针指向子类对象时,此时子类对象中的(父类的虚函数表指针)所指的虚函数表中的(父类重写虚函数的地址)被改写为(子类的重写虚函数的地址),所以此时父类指针访问子类中父类的虚函数表时,找到的要调用的同名虚函数的地址就是子类的同名虚函数地址;所以父类指针调用就是子类的重写的同名虚函数;
虚函数重写(覆盖)的实质就是重写父类虚函数表中的父类虚函数地址;
4. 虚表指针初始化问题,当创建子类对象时,编译器的执行顺序:
· 对象在创建时,由编译器对 vptr 进行初始化
· 子类的构造会先调用父类的构造函数,这个时候 vptr 会先指向父类的虚函数表
· 子类构造的时候,vptr 会再指向子类的虚函数表(这也就是在父类或者子类的构造函数中调用虚成员函数不会实现多态的原因)
· 对象的创建完成后,vptr 最终的指向才确定
5. C++类继承中的构造函数和析构函数和多态的关系
a.构造函数不能实现多态:
子类的构造会先调用父类的构造函数,这个时候 vptr 会先指向父类的虚函数表;子类构造的时候,vptr 会再指向子类的虚函数表;
b. 析构函数可以实现多态:
在用基类指针指向派生类时,在基类析构函数声明为virtual的时候,delete基类指针,会先调用派生类的析构函数,再调用基类的析构函数;
c. 注意事项:在基类析构函数没有声明为virtual的时候,delete基类指针,只会调用基类的析构函数,而不会调用派生类的析构函数,这样会造成销毁对象的不完全;
C++多态及其实现原理的更多相关文章
- c++编译器对多态的实现原理总结
问题:定义一个空的类型,里面没有任何的成员变量或者成员函数,对这个类型进行 sizeof 运算,结果是? 结果是1,因为空类型的实例不包含任何信息,按道理 sizeof 计算之后结果是0,但是在声明任 ...
- Java 多态的实现原理
一个对象变量可以指示多种实际类型的现象称为多态 允许不同类的对象对同一消息做出响应.方法的重载.类的覆盖正体现了多态. 1.多态的机制 1.1 本质上多态分两种 .编译时多态(又称静态多态) .运行时 ...
- 多态原理探究-从C++编译器角度理解多态的实现原理
理论知识: 当类中声明虚函数时,编译器会在类中生成一个虚函数表. 虚函数表是一个存储类成员函数指针的数据结构. 虚函数表是由编译器自动生成与维护的. virtual成员函数会被编译器放入虚函数表中. ...
- c/c++ 多态的实现原理分析
多态的实现原理分析 当类里有一个函数被声明成虚函数后,创建这个类的对象的时候,就会自动加入一个__vfptr的指针, __vfptr维护虚函数列表.如果有三个虚函数,则__vfptr指向的是第一个虚函 ...
- 从虚拟机指令执行的角度分析JAVA中多态的实现原理
从虚拟机指令执行的角度分析JAVA中多态的实现原理 前几天突然被一个"家伙"问了几个问题,其中一个是:JAVA中的多态的实现原理是什么? 我一想,这肯定不是从语法的角度来阐释多态吧 ...
- Java技术——多态的实现原理
.方法表与方法调用 如有类定义 Person, Girl, Boy class Person { public String toString(){ return "I'm a person ...
- java多态的实现原理(JVM调用过程)(综合多篇文章,参考见文末)
一个对象变量可以指示多种实际类型的现象称为多态 允许不同类的对象对同一消息做出响应.方法的重载.类的覆盖正体现了多态. 1.多态的机制 1.1 本质上多态分两种 1.编译时多态(又称静态多态) 2.运 ...
- c++的动态绑定和静态绑定及多态的实现原理(摘)
C++多态的实现原理 为了支持c++的多态性,才用了动态绑定和静态绑定.理解它们的区别有助于更好的理解多态性,以及在编程的过程中避免犯错误. 需要理解四个名词:对象的静态类型:对象在声明时采用的类型. ...
- C++学习笔记-多态的实现原理
深入了解多态的实现原理,有助于提高对于多态的认识 多态基础 多态的实现效果 多态:同样的调用语句有多种不同的表现形态 多态实现的三个条件 有继承.有virtual重写.有父类指针(引用)指向子类对象 ...
- C++ 一篇搞懂多态的实现原理
虚函数和多态 01 虚函数 在类的定义中,前面有 virtual 关键字的成员函数称为虚函数: virtual 关键字只用在类定义里的函数声明中,写函数体时不用. class Base { virtu ...
随机推荐
- dsu on tree 树上启发式合并 学习笔记
近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数) ...
- python学习笔记之元祖
#元祖 只读列表,可循环查询,可切片.#儿子不能改,孙子可能可以改. tu = (1,2,3,'alex',[2,3,4,'taibai'],'egon') print(tu[3]) print(tu ...
- (七) UVC框架分析
title: UVC框架分析 date: 2019/4/23 19:50:00 toc: true --- UVC框架分析 源码的位置在drivers\media\video\uvc,查看下Makef ...
- Docker实践之01-入门介绍
目录 一.Docker概述 镜像 容器 仓库 二.安装Docker 1.在CentOS上安装Docker 2.在Ubuntu上安装Docker 3.启动docker 4.建立Docker用户组 5.测 ...
- Ajax简述
AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术.AJAX = 异步 JavaScript和X ...
- Exp4 恶意代码分析 20164314
一.实践目标 1.是监控你自己系统的运行状态,看有没有可疑的程序在运行. 2.是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals,systr ...
- windows8.1全角与半角切换快捷键
windows8.1全角与半角切换快捷键: shift + 空格
- 同一台电脑同时装jdk1.8和jdk1.7
因为之前安装的eclipse版本要求JDK1.8或以上的版本,但在搭建SSH框架的时候老是报错,又找不到2错误源.老师建议换个低版本的jdk.所以jdk版本需要降级. 但降级以后就不能打开eclips ...
- Python:正则表达式(二):如何使用re.search()返回的匹配对象中的具体内容呢??
在上一篇中讲述了re.seach()会返回一个对象格式的数据,如下:<_sre.SRE_Match object; span=(16, 24), match='${phone}'> 那么问 ...
- Pytorch如何用预训练模型提取图像特征
方法很简单,你只需要将模型最后的全连接层改成Dropout即可. import torch from torchvision import models # load data x, y = get_ ...