随笔 - 576  文章 - 0  评论 - 62  阅读 - 219万

理解virtual方法

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,告诉编译器,不要通过上面的方式决议方法。

posted on   Andy Niu  阅读(2485)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示