关于虚函数

虚函数实现了C++的多态特性。

重写虚函数,虚函数的参数类别和个数不可以改变,返回值类型也不可以改变。存在一个例外,当A类的虚函数返回A类指针,B类继承后返回B类指针,但要求A类指针和B类指针可以相互转换。覆盖和重写为一个意思,重载则不同。

可以分为纯虚函数和虚函数,

  •   对于父类的纯虚函数,子类在继承之后必须实现不然子类无法实例化。
  •   而对于虚函数,子类可以选择覆盖也可不覆盖。

final和override关键字。

override跟在覆盖后的虚函数,可以防止不小心修改了参数类型或者个数,此时编译器会报错。

final关键字表示该函数不能进行覆盖。

可以同时使用override和final修饰,因为他们不冲突而且可以使编译器和用户更好理解。

当父类的非虚函数,子类对其重写之后。如果使用子类的对象调用该函数或者子类对象的指针调用该函数,则运行子类的重写版本,但是如果是父类指针指向子类对象,进行调用那么不会调用子类函数而是父类的函数。

eg1:

Father* p=new Son();

p->func();此时会调用父类的func();

eg2:

Son son;或者Son *son=new Son();

son.func();调用子类的fun()

对于该现象的理解

  虚函数机制是动态的,也就是可以在运行时确定调用的函数。然后如果是非虚函数的重写,父类指针无法找到子类对应的函数,只能调用自身的函数。

既然可以用子类对象调用子类函数,那么为什么需要使用虚函数机制?

  实际开发过程中,当我们使用一些基类、框架的时候,它们是事先写好的,使用的时候不能修改库函数的源码,只能同派生类来重新实现库函数。有些库函数由框架调用,因此使用虚函数是一个好的解决方法。

虚函数指针和虚函数表的理解:

  当我们的父类声明虚函数,每个子类会有一个虚函数指针指向虚函数表。当子类重写虚函数之后,那么子类重新实现实现的虚函数就会覆盖掉虚函数表中的函数。此时使用父类指针调用子类函数的时候就可以找到子类实现的版本。

  但是如果不是虚函数。那么仅仅只是重名函数 没有使用到函数指针调用,因此只是函数调用,那么父类指针也就无法调用子类的函数。

  此外父类指针也不能调用子类独有的虚函数,基于父类不应该能插手子类自己的数据的原则。

posted @   海蓝笨  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示