一、函数重载(Function Overloading)
为了更加深刻的理解 函数重载、重写、重定义,我们可以带着如下这两个问题去思考:
1、子类中是否可以定义父类中的同名成员?为什么?
可以,因为子类与父类的命名空间不同;
2、子类中定义的函数是否可以重载父类中的同名函数?
不可以,因为函数重载必须在同一个作用域中。
1、什么是函数重载
在同一个类中(同一个作用域中/在类的内部),存在一组函数名相同,函数的参数列表不同(参数的个数、类型、顺序),函数有无 virtual 关键字都可以,我们把这组函数称为函数重载。
2、为什么使用函数重载(函数重载的好处)
由于函数重载可以在同一个作用域内,使用同一个函数名 命名一组功能相似的函数,这样做减少了函数名的数量,避免了程序员因给函数名命名所带来的烦恼,从而提高程序的开发的效率。
3、函数重载的条件
1. 必须在同一作用域下
2. 函数名相同但是参数列表不同(参数列表的 类型 or 个数 or 顺序 不同)
3. 返回值的类型不会影响重载
4. const属性相同
4、函数重载的原理(本质:c++编译器对同名函数进行重命名)
编译器在编译.cpp文件中当前使用的作用域里的同名函数时,根据函数形参的类型和顺序会对函数进行重命名(不同的编译器在编译时对函数的重命名标准不一样);
但是总的来说,他们都把文件中的同一个函数名进行了重命名;
在vs编译器中:
根据返回值类型(不起决定性作用)+形参类型和顺序(起决定性作用)的规则重命名并记录在map文件中。
在linux g++ 编译器中:
根据函数名字的字符数+形参类型和顺序的规则重命名记录在符号表中;从而产生不同的函数名,当外面的函数被调用时,便是根据这个记录的结果去寻找符合要求的函数名,进行调用;
为什么c语言不能实现函数重载?
编译器在编译.c文件时,只会给函数进行简单的重命名;
具体的方法是给函数名之前加上”_”;所以加入两个函数名相同的函数在编译之后的函数名也照样相同;调用者会因为不知道到底调用那个而出错;
5、函数重载的结论
1. 函数重载的本质:多个不同的函数;
2. 函数名和参数列表是唯一的标识;
3. 函数重载必须发生在同一个作用域中;
4. c++编译器 和 c编译器 对函数重命名的规则不同;
5. 编译器决定符号表中函数名被编译后的最终目标名;
c++ 编译器 将函数名和参数列表编译成目标名;
c 编译器将函数名编译成目标名;
6. 函数重载是在编译期间根据参数类型和个数决定函数调用
7. 函数重载是一种静态多态;
(1)多态:用同一个东西表示不同的形态;
(2)多态分为:静态多态(编译时的多态)、动态多态(运行时的多态);
6、编译器调用函数重载的规则
1. 将所有同名函数作为候选者;
2. 尝试寻找可行的候选者函数
(1)精确匹配实参;
(2)通过默认参数能够匹配实参;
(3)通过默认类型转换匹配实参;
3. 匹配失败
(1)最终寻找的候选函数不唯一,则出现二义性,编译失败;
(2)无法匹配所有的候选函数,函数没定义,编译失败;
7、函数重载与默认参数
当函数重载遇到默认参数时,就会发生二义性;
代码如下:
#include<iostream>
using namespace std;
class A
{
void func(int a, int b, int c = 0) {
}
void func(int a, int b) {
}
};
int main