1)什么是函数重载?
函数重载:在同一个作用域内,函数名字相同,参数(个数,顺序,类型)不同 那么就是函数重载
函数重载条件:
- 同一个作用域内
- 函数名字相同
- 参数(个数不同 或 顺序不同 或 类型不同)
编译器会根据实参的类型,匹配一个最合适的函数去调用(存在隐式转换)
注意:函数返回值和函数重载无关
为什么C语言函数名字相同会报错?C++可以重载?
因为C语言函数名字经过编译之后没有改变,C++函数名字编译之后会掺杂参数的类型在里面
二义性问题:给一个参数既可调用第一个函数,也可调用第二个函数
void fun()
{
cout << "没有参数" << endl;
}
void fun(int a)
{
cout << "int" << endl;
}
void fun(float a)
{
cout << "float" << endl;
}
void fun(int a, double b)
{
cout << "int double" << endl;
}
void fun(double a, int b)
{
cout << "double int"<< endl;
}
int main() {
fun();
fun(1);
fun(1.1f);
fun(1,1.2);
fun(1.2, 1);
return 0;
}
2) 函数重载的实现原理是什么?
函数重载是指在同一个作用域内,可以有多个函数名相同但参数列表不同的函数。函数重载的实现原理主要包括以下几个方面:
一、名称修饰(Name Mangling)
在一些编程语言中,如 C++,编译器会对函数名进行修饰,使得不同参数列表的同名函数在编译后的符号表中具有不同的名称。这样,在链接阶段就可以正确地区分和调用不同的重载函数。
例如,对于以下两个重载函数:
void print(int num);
void print(const char* str);
编译器可能会将它们修饰为类似于_print_int和_print_char_star这样的名称,以便在链接时能够准确地找到对应的函数。
二、类型推导和参数匹配
在函数调用时,编译器会根据传入的参数类型和数量来确定应该调用哪个重载函数。编译器会尝试将传入的参数与各个重载函数的参数列表进行匹配,选择最匹配的函数进行调用。
1. 精确匹配:如果传入的参数类型与某个重载函数的参数类型完全一致,那么这是最精确的匹配。
2. 类型转换匹配:如果没有精确匹配的函数,编译器会尝试进行类型转换,以找到最接近的匹配
3. 可变参数匹配:在一些编程语言中,可以定义接受可变数量参数的函数,这也可以看作是一种特殊的函数重载。
三、函数调用的解析过程
当编译器遇到一个函数调用时,它会按照以下步骤来确定应该调用哪个重载函数:
- 首先,编译器会检查函数调用的上下文,确定可能的作用域和命名空间。
- 然后,编译器会在当前作用域中查找所有同名的函数,并将它们作为候选函数。
- 接下来,编译器会根据传入的参数类型和数量,对候选函数进行参数匹配。如果有多个函数都可以匹配,编译器会选择最精确的匹配。如果没有精确匹配的函数,编译器会尝试进行类型转换,以找到最接近的匹配。
- 如果仍然无法确定应该调用哪个函数,编译器可能会发出错误信息,提示函数调用不明确。
函数重载的实现原理是通过编译器对函数名进行修饰、类型推导和参数匹配以及函数调用的解析过程来实现的。这样可以提高代码的可读性和可维护性,使得程序员可以根据不同的参数类型和数量来定义多个同名的函数,而不必为每个函数取不同的名称。