3.5 函数重载

简介

Tips:不允许两个函数除了返回类型外其他所有的要素都相同,即不能基于返回类型的重载。

如果同一作用域内的几个函数名字相同但是形参列表不同,我们称之为重载函数。对于重载的函数,它们应该在形参数量或者形参类型上有所不同。

重载与const形参

1. 顶层const

Tips:一个拥有顶层const形参的函数无法和另一个没有顶层const形参的函数区分开。

// 错误: 重复声明foo(string)函数
void foo(string);
void foo(const string);

// 错误: 重复声明foo(string*)函数
void bar(string*);
void bar(string* const);

2. 底层const

Tips:const引用形参的函数可以和非const引用形参的函数区分开。

如果形参是某种类型的指针或引用,则通过区分其指向的是常量对象还是非常量对象可以实现函数重载:

// 正确
void foo(string&);
void foo(const string&);

// 正确
void bar(string*);
void bar(const string*);

const_cast与重载

Tips:const_cast最常用于重载函数的情景。

// 常量引用的函数版本
const string &shorterString(const string &s1, const string &s2) {
    return s1.size() <= s2.size() ? s1 : s2;
}

// 非常量引用的函数版本复用常量引用的函数版本
string &shorterString(string &s1, string &s2) {
    const string &r = shorterString(const_cast<const string&>(s1),
                                    const_cast<const string&>(s2));
    return const_cast<string &>(r);
}

调用重载函数

调用重载函数时有三种可能的结果:

  • 编译器找到一个与实参最佳匹配的函数,并生成调用该函数的代码

  • 找不到任何一个函数与调用的实参匹配,这时候编译器发出无匹配的错误信息

  • 有多于一个函数可以匹配,但是每一个都不是明显的最佳选择,此时会发生二义性调用的错误