博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
理解virtual方法
阅读量:7047 次
发布时间:2019-06-28

本文共 759 字,大约阅读时间需要 2 分钟。

1、使用场景

  virtual方法的使用场景:父类告诉子类,继承接口,修改实现,从而可以面向接口编程。

  non-virtual方法的使用场景:父类告诉子类,继承接口和实现,从而可以代码复用。

2、成员方法是一种封装技术,暴露给程序员。对于编译器而言,没有成员方法的概念,编译器会把成员方法编译为普通方法,方法的拥有者(也就是对象)转化为普通方法的形参,这个形参是const指针,名称为this,指向的类型是方法拥有者的类型。

3、编译器编译的时候,只知道指针的表面类型,正是这个表面类型引导编译器去解释指向对象的大小和内容,那么问题来了?

  对于non-virtual方法,子类继承接口和实现,继承的方法中,this指针的表面类型是什么? 答案是:Base

  对于virtual方法,子类继承了接口,修改了实现,重写的方法中,this指针的表面类型是什么?答案是:Derived

4、思考一下,运行时多态,为什么一定要标记一下方法是virtual?

  考虑,Base和Derived都有一个方法Say,形参表一样(这里会发生隐藏)。

  Base::Say() 转化为Say(Base* const this),

  Derived::Say()转化为Say(Derived* const this),

  Base* pb = new Derived();

  现在调用pb->Say(); 分析一下,调用父类还是子类方法?

  pb->Say()转化为 Say(pb); 编译器只知道表面类型,根据表面类型决议方法,pb表面类型是Base,因此调用Base::Say,也就是说,指向子类的父类指针不能完成运行时多态。

  通过给父类的方法加上一个virtual,告诉编译器,不要通过上面的方式决议方法。

转载地址:http://vlzol.baihongyu.com/

你可能感兴趣的文章
Using Autorelease Pool Blocks
查看>>
spring-struts-mybatis整合错误集锦
查看>>
Maven 通过maven对项目进行拆分、聚合(重点)
查看>>
TWaver版3D化学元素周期表
查看>>
Java 中最常见的 5 个错误
查看>>
[AWS vs Azure] 云计算里AWS和Azure的探究(2)
查看>>
查看是否安装.NET Framework、.NET Framework的版本号、CLR版本号
查看>>
数据结构基础温故-5.图(下):最短路径
查看>>
调试Release发布版程序的Crash错误(转)
查看>>
深入浅出话VC++(2)——MFC的本质
查看>>
跟我一起学WCF(5)——深入解析服务契约[上篇]
查看>>
Kinect应用开发实战:用最自然的方式与机器对话
查看>>
JavaScript验证手机号码
查看>>
微软免费杀毒软件MSE最新版本释出
查看>>
诊断 Java 代码: 提高 Java 代码的性能 尾递归转换能加快应用程序的速度,但不是所有的 JVM 都会做这种转换...
查看>>
一次数据库hang住的分析过程
查看>>
ArcGIS使用字体文件制作符号库!
查看>>
Cocoa框架类之间的继承关系
查看>>
Windows安全认证是如何进行的?
查看>>
dll文件
查看>>