You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++从抽象祖父类重写非virtual函数触发override报错原因求解

C++ override关键字与virtual的关联规则说明

核心原因

override是C++11引入的编译期校验关键字,仅作用于虚函数重写场景,要求被修饰的函数必须同时满足两个条件:

  • 父类存在同签名(函数名、参数列表、const属性、返回值完全匹配)的成员函数
  • 父类的该成员函数必须被virtual关键字修饰(即属于可重写的虚函数)
    你代码中祖父类A的foo未加virtual,不属于可重写的虚函数,子类C2的foo加override自然无法通过编译校验。

非virtual函数同名实现的本质:名字隐藏

如果你把C2中foo的override修饰符去掉,代码可以正常编译,但此时子类的foo不属于重写,属于名字隐藏,二者行为差异非常大:

  • 名字隐藏场景:只有用子类C2类型的指针/实例调用foo才会走C2的实现,只要用父类A或B的指针指向C2实例调用foo,都会走A的原始实现,不存在多态效果。
  • 虚函数重写场景:只要基类foo加了virtual,不管用A、B还是C2类型的指针指向C2实例,调用foo都会走C2的实现,符合多态的重写预期。

代码补充说明

你当前代码中A的foo函数定义存在笔误:函数声明后多写了一个分号,修正后代码才能正常编译。另外你注释中c2->foo()的输出结果分两种情况:

  1. 未给A的foo加virtual,且去掉C2foo的override:输出foo c1,但A* ptr = c2; ptr->foo();输出foo
  2. 给A的foo加virtual后:不管用什么类型的指针调用C2实例的foo,都输出foo c1

内容的提问来源于stack exchange,提问作者Anoop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 23:06:04