C++继承与重载方法行为的标准合规性确认
C++重载匹配与继承的标准保证
示例代码
#include <iostream> class A {}; class B : public A {}; class Q : public A {}; class C : public B {}; void doOverload(const A& v) { std::cout << __PRETTY_FUNCTION__ << std::endl; } void doOverload(const B& v) { std::cout << __PRETTY_FUNCTION__ << std::endl; } void doOverload(const C& v) { std::cout << __PRETTY_FUNCTION__ << std::endl; } int main() { A a; B b; C c; Q q; doOverload(a); doOverload(b); doOverload(c); doOverload(q); }
运行输出(GCC编译)
void doOverload(const A&) void doOverload(const B&) void doOverload(const C&) void doOverload(const A&)
问题解答
这个行为是完全被C++标准所保证的,核心逻辑来自重载决议中对转换序列优先级的明确规定:
在重载决议阶段,编译器会为每个候选函数计算实参到形参的转换序列,最终选择转换序列最优的函数:
- 当实参是派生类对象时,匹配对应派生类类型的形参属于精确匹配,无需任何类型转换,优先级最高;
- 如果没有对应派生类的重载版本,才会考虑派生类到基类的转换(属于标准转换序列的一种),这种转换的优先级低于精确匹配;
- 对于同一继承体系的类型,更具体的派生类匹配(比如
C类型实参匹配const C&形参),优先级高于匹配其基类(B或A)的重载。
对应C标准中的关键条款(以C20为例):
- 重载决议的整体流程定义在
[over.match]章节; - 转换序列的优先级排序规则在
[over.ics.rank]章节,其中明确规定精确匹配的转换序列优于派生类到基类的转换序列,且更具体的派生类匹配优先级高于较泛化的基类匹配。
所有符合C++标准的编译器都必须遵循这一规则,因此你观察到的行为是可移植的,并非GCC特有的实现。
内容的提问来源于stack exchange,提问作者Patrick Wright
相关产品推荐
相关产品推荐

