C++ 函数
1. 函数重载
- 定义
在相同作用域中可以定义相同函数名的函数,但是它们的参数必须有所区分,这样的多个函数将就构成了重载关系,重载函数通过函数的参数唯一标识区分函数,在调用时将会通过参数的不同来区分构成重载关系的函数 - 函数重载的匹配原则
- 函数是否构成重载关系与函数的返回值类型无关
- 通过函数指针调用重载关系的函数,由函数指针的类型决定匹配重载的版本
- 调用重载关系的函数时,编译器会根据形参和实参的匹配程度,选择最优的匹配版本,一般的匹配规则:
完全匹配>=常量转换>升级转换>降级转换>省略号转换
- 函数重载的原理
编译器在编译时会将函数进行换名,将函数参数表中的信息整合到新的函数名字中,解决函数重载时名字冲突的问题
注意:
编译器换的名字会体现出参数表参数的一些信息 extern "C"
与函数重载的关系
C++中extern "C"
的作用
用g++编译c文件时会对其中的函数进行一个换名操作,后面再用原函数名找该函数,就会找不到
可以在C++函数前面加入extern "C"声明,要求C++的编译器按照C语言的方式编译该函数,不对其进行换名;
这样可以方便C程序直接调用.
注:
被extern "C"
声明的函数不能构成重载关系
2. 函数参数
1> 函数的哑元参数
- 定义
定义函数时,只有数据类型没有变量名的参数被称为哑元,哑元参数没有实际意义
void func(int/*哑元*/){...};
- 哑元参数的使用场景
- 在操作符重载函数(operator)中区分前后++(–),在后++(–)的操作符重载的函数参数中会有一个哑元参数,
- 兼容旧代码,在代码维护升级以后,有的参数可能会不使用了,但是为了不改变接口函数的参数,可以和旧代码可以兼容,就可以使用哑元参数
2> 函数的缺省参数(默认实参)
- 在C++函数中可以为部分参数也可以是全部参数指定缺省值,调用该函数时,如果没有传递实参,就用缺省参数作为默认实参
void func(int falg = 0/*缺省参数*/){...}
- 缺省参数靠右原则
函数中的所有的缺省参数都应在参数表中靠右对齐, - 如果函数的定义和声明分开写,缺省参数应该写在函数的声明部分,定义部分不写
#include <iostream>
using namespace std;
void func(int a = 10,int b = 20,int c = 30);
int main (void){
func(11,22,33);//11,22,33
func();//10,20,30
func(11);//11,20,30
func(11,22);//11,22,30
return 0;
}
void func(int a/* = 10*/,int b/* = 20*/,int c/* = 30*/){
cout << "a="<< a <<", b=" << b << ", c=" << c << endl;
}
$ g++ defArg.cpp -o defArg
$ ./defArg
a=11, b=22, c=33
a=10, b=20, c=30
a=11, b=20, c=30
a=11, b=22, c=30
内联函数(inline)
-
定义
在函数声明时用关键字 inline 修饰的函数是一个内联函数,编译器会尝试对这个内联函数进行内联优化,可以避免函数调用的开销(调用跳转的消耗),提高代码的执行效率(以空间换时间)
inline void func(void){...}//内联函数
-
适用内联函数的场景
- 多次调用小而简单的函数,适合做内联优化
- 调用次数极少或大而复杂的函数不适合内联优化
- 递归函数不适合内联优化(编译器无法确定替换次数)
- 虚函数不适合内联优化
- 注意
- 内联对编译来说只是一种建议而不是强制要求,一个函数能否做内联优化主要取决于编译器,有些函数不加inline修饰,也会默认处理为内联优化的函数,有些函数即便加了inline关键字也会被编译器忽略
- 内联优化会使函数的执行流程变的连贯,代码的执行效率会的到提高