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 ...
随机推荐
-
hibernate(二)annotation第一个示例
一.在数据库中创建teacher表(数据库hibernate) create table teache( id int auto_increment primary key, name ), titl ...
-
Android开发常见问题系列之一:eclipse中adb.exe启动失败或者无法启动
这种情况下大多数是因为存在kadb.exe在执行,或者adb.exe端口被占用. 1,检查是否存在kadb.exe程序正在执行 打开任务管理器,打开详细信息,按照字母顺序找到kadb.exe,结束进程 ...
-
iOS开发UI篇—在UIImageView中添加按钮以及Tag的参数说明
ios开发UI篇—在ImageView中添加按钮以及Tag的参数说明 一.tag参数 一个视图通常都只有一个父视图,多个子视图,在开发中可以通过使用子视图的tag来取出对应的子视图.方法为Viewwi ...
-
js判断是否安装pdf播放器
function isPDFPluginInstall() { if (!isIE()) { //ie 浏览器 和 非ie浏览器支持 // not ie if (navigator.plugins & ...
-
WinCE发展史
Windows CE概述 WindowsCE是微软公司嵌入式.移动计算平台的基础,它是一个开放的.可升级的32位嵌入式操作系统,是基于掌上型电脑类的电子设备操作系统,它是精简的Windows 95,W ...
-
多个分布式系统如何共享使用一个固定公网IP
传统的做法,一个分布式业务系统就有一个中间件,一个中间件需要使用至少一个固定公网IP,这样的话,多个业务系统就需要使用多个固定公网IP. 大家知道,固定公网IP价格可是不菲的.能不能让多个分布式业务系 ...
-
scala的break和continue
scala 是没有 continue 的,但是包含 break,可以用 break 构造出 continue 的效果 这里用到了库: import scala.util.control.Breaks. ...
-
poj-1807(最大流)
题意:给你n个插座,m个电器,每个电器有插头,还有k个插头转换器,可以把插座A变成插座B,转换器可以连续使用,比如A转换B,再从B转换C 解题思路:这道题就是题意麻烦,看懂了就很简单,首先建一个汇点和 ...
-
【转】服务化框架技术选型与京东JSF解密
[京东技术]声明:本文转载自微信公众号“开涛的博客”,转载务必声明. 作者:章耿,原京东资深架构师,曾负责京东服务框架,配置中心等基础平台.近十年工作经验,专注于基础中间件等底层技术架构,对分布式系统 ...
-
linux抓包命令之tcpdump
顾名思义,tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析.它支持针对网络层.协议.主机.网络或端口的过滤,并提供and.or.not等逻辑语句来帮助你去掉无用的信息,tcpdump ...