函数重载

同一个作用域内的几个函数名字相同但是形参列表不同,称之为重载函数。

  • main 函数不可以重载。
  • 对于重载函数应该在形参数量和形参类型上有所有差异:
    • 只有返回值不同的函数不能构成重载。
    • 一个拥有顶层 const 和另一个没有顶层 const 的形参无法构成重载。

const_cast 与重载

const string &shorterString(const string &str1, const string &str2)
{
	return str1.size() <= str2.size() ? str1 : str2;
}

上面的函数传入的是常量引用,返回的也是常量引用。我们可以对两个非常量引用调用该函数,但是返回值仍然是常量引用。

如果我们需要更新一个函数,当该函数的传入参数非常量引用,返回一个非常量引用:

string &shorterString(string &s1, string &s2)
{
	auto &r = shorterString(const_cast<const string&>(s1), const_cast<const string&>(s2)); //实参强制类型转换
	
	return const_cast<string&>(r);
}

返回值r一定是绑定了某个初始的非常量的实参上,所以这里是安全。

调用重载函数

函数匹配是指一个过程,在这个过程中把函数与一组重载函数中的某一个关联起来,函数匹配也叫重载确定

编译器会将实参与重载集合的每一个函数进行比较,然后根据比较的结果确定调用哪个函数。

调用重载函数的三种结果:

  • 编译器找一个最佳匹配的函数,并生成调用该函数的代码。
  • 找不到任何一个函数与调用的实参匹配,此时编译器发出无匹配的错误。
  • 有多个函数可以匹配,但是每一个都不是最明显的最佳选择,此时也将发生错误,称为二义性错误。

重载与作用域

重载对于作用域的一般性质并没有发生改变,如果在内层作用域中声明了名字,它将隐藏外层作用域中声明的同名实体。在不同的作用域中无法重载函数名:

string read();
void print(const string &);
void print(double);  //重载print函数

void fooBar(int ival)
{
	bool read = false;	//新作用域:隐藏了外层的read
	string s = read(); //错误,read是一个bool值,而非函数

	//不好的习惯,局部作用域中声明函数是一个很不好的选择
	void print(int);	//新作用域:隐藏了外层的print

	print("value");		//错误,print(const string &)被隐藏了
	print(ival);		//正确
	print(3.14);		//正确,调用print(int),print(double)被隐藏了
}
原文地址:https://www.cnblogs.com/xiaojianliu/p/12498099.html