C++多态的实现原理

为了支持c++的多态性,才用了动态绑定和静态绑定。理解它们的区别有助于更好的理解多态性,以及在编程的过程中避免犯错误。

需要理解四个名词:对象的静态类型:对象在声明时采用的类型。是在编译期确定的。

对象的动态类型:当前对象的类型。是在运行期决定的。

对象的动态类型可以更改,但是静态类型无法更改。

注:要实现动态绑定一定要使用指针或者引用来调用。

  1. class B
  2. {
  3. }
  4. class C : public B
  5. {
  6. }
  7. class D : public B
  8. {
  9. }
  10. D* pD = new D();//pD的静态类型是它声明的类型D*,动态类型也是D*
  11. B* pB = pD;//pB的静态类型是它声明的类型B*,动态类型是pB所指向的对象pD的类型D*
  12. C* pC = new C();
  13. pB = pC;//pB的动态类型是可以更改的,现在它的动态类型是C*

静态绑定:绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。(对象在编译时期根据其实际的类型(静态类型)调用相应的函数)

动态绑定:绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。(对象在运行时期根据其实际的类型(动态类型)调用相应的函数)

  1. class B
  2. {
  3. void DoSomething();
  4. virtual void vfun();
  5. }
  6. class C : public B
  7. {
  8. void DoSomething();//首先说明一下,这个子类重新定义了父类的no-virtual
  9. //函数,这是一个不好的设计,会导致名称遮掩;这里只是为了说明动态绑定和静态
  10. //绑定才这样使用。
  11. virtual void vfun();
  12. }
  13. class D : public B
  14. {
  15. void DoSomething();
  16. virtual void vfun();
  17. }
  18. D* pD = new D();
  19. B* pB = pD;
  • pD->DoSomething()和pB->DoSomething()调用的是同一个函数吗?

  • 不是的,虽然pD和pB都指向同一个对象。因为函数DoSomething是一个no-virtual函数,它是静态绑定的,也就是编译器会在编译期根据对象的静态类型来选择函数。pD的静态类型是D,那么编译器在处理pD->DoSomething()的时候会将它指向D::DoSomething()。同理,pB的静态类型是B,那pB->DoSomething()调用的就是B::DoSomething()。

  • pD->vfun()和pB->vfun()调用的是同一个函数吗?

  • 是的。因为vfun是一个虚函数,它动态绑定的,也就是说它绑定的是对象的动态类型,pB和pD虽然静态类型不同,但是他们同时指向一个对象,他们的动态类型是相同的,都是D*,所以,他们的调用的是同一个函数:D::vfun()。

  • 只有虚函数才使用的是动态绑定,其他的全部是静态绑定。

  • 当缺省参数和虚函数一起出现的时候情况有点复杂,极易出错。我们知道,虚函数是动态绑定的,但是为了执行效率,缺省参数是静态绑定的。

  1. class B
  2. {
  3. virtual void vfun(int i = );
  4. }
  5. class D : public B
  6. {
  7. virtual void vfun(int i = );
  8. }
  9. D* pD = new D();
  10. B* pB = pD;
  11. pD->vfun();
  12. pB->vfun();

pD->vfun()和pB->vfun()调用都是函数D::vfun(),但是他们的缺省参数是多少?缺省参数是静态绑定的,pD->vfun()时,pD的静态类型是D*,所以它的缺省参数应该是20;同理,pB->vfun()的缺省参数应该是10。

绝不重新定义继承而来的缺省参数

c++的动态绑定和静态绑定及多态的实现原理(摘)的更多相关文章

  1. C++ 多态Polymorphism 介绍+动态绑定、静态绑定

    什么是多态? 多态(polymorphism)一词最初来源于希腊语polumorphos,含义是一种物质的多种形态. 在专业术语中,多态是一种运行时绑定机制(run-time binding) ,通过 ...

  2. Java动态绑定和静态绑定-多态

    一.问题 Java方法调用过程中,Jvm是如何知道调用的是哪个类的方法?Jvm又是如何处理?   二.概念 a.当子类和父类(接口和实现类)存在同一个方法时,子类重写父类(接口)方法时,程序在运行时调 ...

  3. 再次探讨C++的动态绑定和静态绑定

    以前在学习C++的时候,对动态绑定和静态绑定的理解是:静态绑定是编译时决定的,非虚函数基本都是静态绑定:而动态绑定用于虚函数,是为了实现多态.这样理解没什么大的问题,但我一直疑惑的是,既然静态绑定可以 ...

  4. java动态绑定与静态绑定【转】

    程序绑定的概念: 绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来.对java来说,绑定分为静态绑定和动态绑定:或者叫做前期绑定和后期绑定.静态绑定: 在程序执行前方法已经被绑定(也就是说在 ...

  5. 关于继承的基本知识,方法重写,final和abstract的使用, 动态绑定和静态绑定的知识

    一.继承: 涉及关键字: extends(继承) super final abstract 特点: 1.类与类之间可以用 XX是XX来描述 , 那么他们之间就存在继承关系.  2.Java中不支持多继 ...

  6. 深入理解C++的动态绑定和静态绑定【转】

    转自:http://blog.csdn.net/chgaowei/article/details/6427731 为了支持c++的多态性,才用了动态绑定和静态绑定.理解他们的区别有助于更好的理解多态性 ...

  7. c++动态绑定与静态绑定

    C++为了支持多态性,采用了动态绑定和静态绑定 相关概念: 对象的静态类型:对象在声明时采用的类型,编译时确定 对象的动态类型:目前所指对象的类型,在运行时确定 class B { } class C ...

  8. c++的动态绑定和静态绑定

    为了支持c++的多态性,才用了动态绑定和静态绑定. 1.对象的静态类型:对象在声明时采用的类型.是在编译期确定的. 2.对象的动态类型:目前所指对象的声明.在运行期决定.对象的动态类型可以更改,但是静 ...

  9. 【转】深入理解C++的动态绑定和静态绑定 & 不要重定义虚函数中的默认参数

    为了支持c++的多态性,才用了动态绑定和静态绑定.理解他们的区别有助于更好的理解多态性,以及在编程的过程中避免犯错误.需要理解四个名词:1.对象的静态类型:对象在声明时采用的类型.是在编译期确定的.2 ...

随机推荐

  1. 05 Mybatis的CRUD操作和Mybatis连接池

    1.CRUD的含义 CRUD是指在做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete)几个单词的首字母简写.主要被用在描述软件系统中 ...

  2. (四)linux 学习 --使用命令

    The Linux Command Line 读书笔记 - 部分内容来自 http://billie66.github.io/TLCL/book/chap06.html 文章目录 什么是命令 是哪一种 ...

  3. golang程序因未知错误崩溃时如何记录异常

    开发服务器程序时如果未经过充分测试, 服务稳定运行一段时间后会突然崩溃退出.一般是因为程序中出现了某个未捕获的异常. 这类问题属于偶现的,且需要服务器运行一段时间之后才会出现,难以定位有问题的代码段. ...

  4. MySQL数据库-表操作-SQL语句(一)

    1. 数据库操作与存储引擎 1.1   数据库和数据库对象 数据库对象:存储,管理和使用数据的不同结构形式,如:表.视图.存储过程.函数.触发器.事件等. 数据库:存储数据库对象的容器. 数据库分两种 ...

  5. 不一样的go语言-athens源码概览

    前言   上一篇文章介绍了athens私服的安装以及vgo download protocol的简要介绍.本文着重介绍go proxy sever的实现原理以及athens是如何实现的. go get ...

  6. prometheus+alertmanager+granafa监控总结,安装基于docker-compose(长期更新)

    最近自己个人尝试在使用prometheus+grafana监控工作业务上的指标, 但是报警功能还没有实际用上,但是感觉是很好用,写下一些啃prometheus官网文档并且自己用到的一些配置的总结,后续 ...

  7. 计数器的Verilog写法

    计数器是非常基本的使用,没有计数器就无法处理时序.我在学习时发现市面上有几种不同的计数器写法,非常有趣,在此记录下来: 一.时序逻辑和组合逻辑彻底分开(by锆石科技FPGA教程) 1.代码 //=== ...

  8. 集成maven和Spring boot的profile

    如果在配置中勾选了多套配置,则以pom.xml文件中 profiles中  配置 最后一个配置为准. maven中配置profile节点: <project> .... <profi ...

  9. Git命令和使用

    Git & GitHub Git是一个工具,用于命令行操作 GitHub是一个协同工作平台 包括: Remote original Repository - 远程主仓库(上线唯一仓库) Rem ...

  10. Python之TensorFlow的基本介绍-1

    一.TensorFlow™是一个基于数据流编程(dataflow programming)的符号数学系统,被广泛应用于各类机器学习(machine learning)算法的编程实现,其前身是谷歌的神经 ...