c++多态


  前几天和另一个同事聊天,正好聊到了c++编程语言的的三大特性:封装、继承和多态;当时同事随口提起多态的运行机制,由于之前对这方面没有完全理解,所以回来就做了一个实验,以加深对多态机制的印象,顺便记录下来,以便后面还可以review;
多态的概念:

  什么是多态?
  官方解释为“在不同继承关系的类对象,去调同一函数,产生了不同的行为”;
  我个人认为,“多态是在继承的基础上,父类和子类同时实现某个使用virtual修饰的方法,在程序运行时,通过动态解析父类指针指向的实际对象,来确定调用的具体实现”;

多态的实现:

  在多态的实现中,需要有类的继承关系,并且父类中的某些方法需要使用关键字virtual修饰,且在子类中可以重写这部分方法;在调用时,当使用父类指针去调用这些使用了virtual修饰的方法时,会根据当前父类指针指向的对象类型来确定调用哪个类的方法;如果一个方法没有使用virtual关键字修饰,且在父类和子类中都有实现,当调用该方法时,会根据指针的类型来确定调用的类;
在这里插入图片描述
  从上面截图中,我们可以看出来,CParent和CSon具有继承关系,CParent是父类,CSon是子类;在父类中,Print方法没有使用virtual修饰,而Display方法使用了virtual修饰,在调用的时候,使用父类指针指向子类对象,当调用Print方法时,调用的是父类的方法,而Display调用的又是子类的方法;这就是映证了刚才上面介绍的调用经过;

  为什么会出现使用了virtual修饰的方法会根据指针所指的对象来确定,而没有使用virtual修饰的方法就是根据指针的类型来判定的呢?让我们来看一下c++针对于有无关键字virtual修饰的方法的处理方式

多态运行机制:

  在c++程序中,确定具体调用的函数有两种方式,一种称之为静态绑定,与之对应的便是动态绑定,他是多态实现的基础。

   静态绑定:和C语言编译时确定函数调用一样,在程序编译时就确定调用的是哪个函数,在编译的二进制文件中,将确定了被调用函数的地址,所以在运行的过程中直接访问指定地址就可以,这种方式在运行时非常的高效;
   动态绑定: 是指在程序运行过程中,需要根据业务的运行,调整对象实例,根据对象的类型来确定调用的具体是哪个对象的方法;动态绑定是基于函数指针的基础上加以实现的;

  类定义的时候,在基类中使用关键字vitrtual修饰方法,在程序运行的时候,系统会为使用了virtual关键字修饰的基类和子类都生成一个虚函数列表,该表中存储了所有的使用关键字virtual修饰的方法的地址,使用这些包含virtual修饰方法的类生成对象的中会有一个虚指针,用以指向虚函数列表;

  在程序运行的时候,当使用父类指针指向子类对象的时候,系统会使用在当前指针指向的对象的虚指针,找到对应的虚函数列表,然后根据调用的函数指针类型以及给定的参数等信息,匹配到对应的函数方法,这样就能够完成调用
在这里插入图片描述
  刚才上面提到了在父类和子类中,当调用没有使用关键字virtual修饰的方法时,会根据生命的指针类型来确定调用的具体方法,这是为什么呢?

   由于子类继承了父类,所以子类中即包含有父类定义的属性也包含有自己特有的;没有使用virtual修饰的方法,在编译的时候就直接确定了调用函数的地址,所以,在调用时,会出现根据定义的指针类型来确定调用函数的现象;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

brid.huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值