-
-
[分享]C++基础七-函数重载
-
2021-8-25 18:35 4656
-
什么是函数重载
在实际开发中,有时候我们需要实现几个功能类似的函数,只是函数内细节不同,例如求图形面积,可以是圆形、长方形、三角形。在C语言中,往往需要分别设计三个不同名的函数,但是在C++中,允许多个函数拥有相同的函数名,只要函数的参数列表不同就可以,这就是函数重载。借助函数重载,一个函数名可以有多种用途。
函数重载的用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | double GetArea(double radius) { return radius * radius * 3.14 ; } double GetArea( int length, int width) { return length * width; } double GetArea(double bottom,double height) { return bottom * height / 2 ; } |
参数列表包括参数类型、参数个数、参数顺序,只要有一个不同就是参数列表不同。
函数重载的规则
- 函数名称必须相同。
- 参数列表必须不同(个数不同、类型不同、排列顺序不同)。
- 函数的返回类型可以相同也可以不相同。
- 仅仅函数的返回类型不同不足以成为函数的重载。
函数重载的原理
编译器在编译.c文件时,只会给函数进行简单的重命名,具体的方法是给函数名之前加上“_”,所以两个函数名相同的函数在编译之后的函数名也相同,调用者会因为不知道到底调用哪个而出错。
编译器在编译.cpp文件中当前使用的作用域里的同名函数时,根据函数形参的类型和顺序会对函数进行重命名,不同的编译器在编译时对函数的重命名标准不一样,但总的来说,他们都把文件中的同一个函数名进行了重命名。
在vs编译器中:
根据返回值类型(不起决定性作用)和形参类型和顺序(起决定性作用)的规则重命名。
在linux g++ 编译器中:
根据函数名字的字符数和形参类型和顺序的规则重命名并记录在符号表中,从而产生不同的函数名,当外面的函数被调用时,根据这个记录的结果去寻找符合要求的函数名进行调用。
从这个角度讲,函数重载仅仅是语法层面的,本质上它们还是不同的函数,占用不同的内存,入口地址也不一样。
函数参数默认值
在C++中,定义函数时可以给形参指定一个默认值,这样调用函数时如果没有给这个形参赋值,那么就使用这个默认值。
函数形参可全部指定默认值,也可部分指定默认值,部分指定的时候,从右向左连续指定,随意指定会出现重定义的错误。
有默认值的函数形参,可不用传递实参,若给有默认值的函数形参传递了实参,默认值会被覆盖掉。
1 2 3 4 5 6 | / / 默认参数应该在声明中提供 void SayHello(const char * name, const char * text = "hello" ); void SayHello(const char * name, const char * text) { cout << text << name << endl; } |
函数重载的二义性
函数重载的二义性指的是在编译过程中无法找出最匹配的函数,或者说编译器在函数匹配过后还是有多个函数满足要求,无法确定该执行哪一个引发的错误。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include <iostream> using namespace std; int Add( int a, int b) { return a + b; } double Add(double a,double b) { return a + b; } double Add(double a,double b,double c = 0 ) { return a + b + c; } int main() { int i = 9 ; double d = 9.9 ; Add(i,i); / / Add(d,d); / / 函数重载二义性,要注意默认参数 / / Add(i,d); / / 函数重载二义性,可以在调用时进行类型转换; Add(i,( int )f); system( "pause" ); return 0 ; } |
github:https://github.com/0I00II000I00I0I0
bilibili:https://space.bilibili.com/284022506
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。