文章目录
- 定义重载函数
- 判断两个形参是否相同
- 重载和const形参
- const_cast和重载
- 调用重载函数
- 重载与作用域
如果同一作用域内的几个函数名字相同但形参列表不同,我们称之为重载函数。但值得注意的是main函数无法重载。
定义重载函数
对于重载的函数来说,它们应该在形参数量或形参类型上有所不同。不允许两个函数除了返回类型外其他所有的要素都相同。
判断两个形参是否相同
可以使用decltype进行相对应的判断。
重载和const形参
如介绍的,顶层const 不影响传入函数的对象。一个拥有顶层const的形参无法和另一个没有顶层const的形参区分开来:
int function(int i){}
int function(const int i){}//错误,重复定义都为顶层const
//
int function(int* p){}
int function(int* const p){}//错误,重复定义都为顶层const
但是如果是底层const的话就可以区分开来了:
int function(int* i){}//指向i的指针(非常量)
int function(const int* i){}//新函数,指向常量的指针
int function(int& i){}//作用于i的引用(非常量)
int function(const int& i){}//新函数,常量的引用
const_cast和重载
主要的应用场合:
样例:
#include<iostream>
#include<string>using namespace std;const string& function(const string& s1,const string& s2 )
{return s1.size() < s2.size() ? s1 : s2;
}string& function(string& s1, string& s2)
{auto& r = function(const_cast<const string&> (s1), const_cast<const string&> (s2));return const_cast<string&>(r);
}int main()
{return 0;
}
在这个版本的函数中,首先将它的实参强制转换成对const 的引用,然后调用了function函数的const版本。const版本返回对const string 的引用,这个引用事实上绑定在了某个初始的非常量实参上。因此,我们可以再将其转换回一个普通的string&,这显然是安全的。
调用重载函数
定义了一组重载函数后,我们需要以合理的实参调用它们。函数匹配是指一个 过程,在这个过程中我们把函数调用与一组重载函数中的某一个关联起来,函数匹配也叫做重载确定。编译器首先将调用的实参与重载集合中每一个函数的形参进行比较,然后根据比较的结果决定到底调用哪个函数。
总而言之,步骤如下:
- 将所有的同名函数作为候选者。
- 尝试寻找可行的候选者.
(1)精确匹配实参类型。
(2)通过默认参数能够匹配的实参类型。
(3)通过默认类型转换匹配实参。 - 最佳匹配(优先级,从上至下,从高到低)
(1)精确匹配。
(2)通过const转化实现匹配(底层const)
(3)通过类型提升实现的匹配
(4)通过算术类型转换实现的匹配。
(5)通过类类型转换实现的匹配
重载与作用域
一般来说,将函数声明置于局部作用域内不是一个明智的选择。对于刚接触C++的程序员来说,不太容易理清作用域和重载的关系。其实,重载对作用域的一般性质并没有什么改变:如果我们在内层作用域中声明名字,它将隐藏外层作用域中声明的同名实体。在不同的作用域中无法重载函数名。
其主要的原因便是:在C++语言中,名字查找发生在类型检查之前。
故我们对于函数的声明应全部写在最外层或者写在一个专门的头文件中。