函数重载本质是编译期名字修饰,编译器根据实参类型、个数、const性等静态匹配唯一函数签名;仅返回值不同不构成重载;参数个数、类型不同可重载,顶层const差异不可重载。
所谓“重载”,不是运行时动态选择,而是编译器在调用点根据实参类型、个数、const性等,静态匹配唯一一个 function name + parameter types 组合。C++ 不允许仅靠返回值类型不同来重载——int foo(); 和 double foo(); 会编译失败。
以下变化构成合法重载:
void print(int) vs void print(int, int)
void func(double) vs void func(std::string)
void f(int) 和 void f(const int) 是同一函数(const int 在形参中等价于 )
const 会影响匹配:void g(int&)、void g(const int&)、void g(int*) 三者可共存const/volatile)和 ref-qualifier(&/&&)也参与重载:void h() const 与 void h() 是不同函数报错如 error: call of overloaded 'foo(...)' is ambiguous,通常因为:
operator int() 和 operator double())nullptr,而重载函数分别接受 int* 和 std::shared_ptr ——两者都可从 nullptr 转换void x(int = 0) 和 void x() 不能共存调试建议:用 static_cast 显式指定目标重载版本,或临时删减其他重载函数缩小排查范围。
子类中定义同名函数,哪怕参数不同,也会隐藏父类所有同名重载版本:
class Base {
public:
void show(int) { }
void show(double) { }
};
class Derived : public Base {
public:
void show(std::string) { } // ← 这会隐藏 Base::show(int) 和 Base::show(double)
};
若想保留父类重载,需显式引入:
class Derived : public Base {
public:
using Base::show; // ← 关键!否则父类所有 show 都不可见
void show(std::string) { }
};
不加 using 声明时,即使 Derived d; d.show(42); 看起来该调用 Base::show(int),也会编译失败。
static_cast,先检查是否无意中隐藏了基类函数,或某个中间类型悄悄提供了多条转换构造函数。