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()的输出结果分两种情况:
- 未给A的
foo加virtual,且去掉C2foo的override:输出foo c1,但A* ptr = c2; ptr->foo();输出foo - 给A的
foo加virtual后:不管用什么类型的指针调用C2实例的foo,都输出foo c1
内容的提问来源于stack exchange,提问作者Anoop
相关产品推荐
相关产品推荐

