函数重载
2023年12月15日 2023年12月15日
多个函数拥有相同的函数名
多个重载函数必须在形参数量或形参类型上有所区别
不满足重载的情况
- 仅返回类型不同
1Record lookup(Account&); 2bool lookup(Account&);
- 值传递 + 顶层const
1Record lookup(Phone); 2Record lookup(const Phone); 3 4Record lookup(Phone*); 5Record lookup(Phone* const); // 顶层const
满足重载的情况
- 引用传递 + 底层const
1Record lookup(Account&); 2Record lookup(const Account&);
- 值传递 + 底层const
1Record lookup(Phone*); 2Record lookup(const Phone*);
当传递一个非常量对象引用或者指向非常量对象的指针时,编译器会优先选择非常量的版本
const_cast和重载
之前提到, const_cast用来移除或增加底层const属性, 且要求关联对象不具有顶层const
const_cast的使用场景多在函数重载中
比如进行字符串长度比较时, 通常是不需要拥有对字符串的写权限
1const string &shorterString(const string &s1, const string &s2) 2{ 3 return s1.size() <= s2.size() ? s1 : s2; 4}
而当我们需要返回较短字符串时, 后续可能需要对较短字符串做处理. 此时则需要一个非常量版本, 返回较短字符串时, 恢复写权限
1string &shorterString(string &s1, string &s2) 2{ 3 auto &r = shorterString(const_cast<const string &>(s1), 4 const_cast<const string &>(s2)); 5 6 return const_cast<string &>(r); 7}
函数匹配
function matching
又称作重载确定 overload resolution
可能的结果有3种
- 编译器也许能找到一个与实参最佳匹配的函数
best match
- 如果找不到任何一个函数与调用的实参匹配, 编译器报错无匹配
no match
- 有多于一个函数可以匹配, 但均不是最佳选择, 如同时支持的隐式类型转换; 编译器报错二义性调用
ambiguous call
调用重载函数时应尽量避免强制类型转换,如果在实际应用中确实需要强制类型转换,则说明设计的形参集合不合理
重载与作用域
1string read(); // 函数 2 3void print(const string &); 4void print(double); 5 6void fooBar(int ival) 7{ 8 bool read = false; // 变量,隐藏外层同名变量或函数(隐藏外层作用域中的同名实体) 9 string s = read(); // 报错 10 11 void print(int); // 隐藏所有外层print函数 12 print("Value"); // 报错 13 print(ival); // 调用void print(int) 14 print(3.14); // 调用void print(int) 15} 16 17// C++中,名字查找发生在类型检查之前