无多重继承冲突时,调用父类未重写的虚方法能否按继承链找首个实现?
问题:调用未重写方法的父类版本是否安全?
调用被重写方法的父类版本时,若不确定父类是否重写该方法,是否始终安全?
另外,在不存在多重继承冲突的前提下,是否总能通过调用
Ancestor4::foo(),让编译器找到继承链中第一个定义foo()的类并调用其实现?
示例代码
#include <stdio.h> class Ancestor1 { public: virtual void foo() = 0; }; class Ancestor2 : public Ancestor1 { public: virtual void foo() { printf("I am ancestor 2\n"); } }; class Ancestor3 : public Ancestor2 { public: virtual void foo() { printf("I am ancestor 3\n"); } }; class Ancestor4 : public Ancestor3 { }; class Descendant : public Ancestor4 { public: virtual void foo() { printf("I am Descendant\n"); Ancestor4::foo(); } }; int main(){ Descendant d; d.foo(); }
运行输出
I am Descendant I am ancestor 3
分析与结论
核心结论
在单继承(无多重继承冲突)的场景下,这种调用是安全且行为确定的,但要注意:这种通过类名::方法名()的调用是静态绑定,而非动态多态的运行时解析。
具体规则说明
- 当你用
Base::func()的形式调用虚函数时,编译器会直接在Base的继承链中向上查找,找到最靠近Base的、提供了func()非纯虚实现的类,并调用该类的方法版本——这个过程在编译阶段就已确定,和运行时的对象类型无关。 - 如果整个继承链中只有纯虚函数的声明(比如
Ancestor1的foo())而没有实现,编译阶段就会直接报错,不会产生运行时问题。 - 只要继承链中存在至少一个非纯虚的
func()实现,这种调用就会编译通过,且行为完全可预测:调用的就是继承链中离你指定的类(比如示例中的Ancestor4)最近的那个实现。
针对问题的回答
- 调用被重写方法的父类版本时,若不确定父类是否重写该方法:只要继承链中存在该方法的非纯虚实现,就是安全的——编译阶段就能确定调用目标,不会出现运行时未定义行为。
- 在无多重继承冲突的前提下:总能通过这种方式找到继承链中第一个(最靠近指定类的)定义该方法的类的实现,这是C++静态绑定规则决定的确定行为。
内容的提问来源于stack exchange,提问作者merlin2011
相关产品推荐
相关产品推荐

