内联函数
inline function在编译后实质上是函数代码块的替换,编译器不一定会实现inline function,如果编译器认为inline function太复杂或者有递归调用。inline function的链接性为内部链接,所以inline function的定义和声明不能放在不同的文件中。
引用类型作函数参数
如果函数的参数为引用类型,如果传递的参数类型正确但不是左值或者传递的参数类型不正确,在其可以转换为正确的类型的情况下,编译将会创建一个临时变量,而将引用参数引用到该临时变量上。
1 | double refcube(const double &ra){ |
带默认参数的函数
- 如果要用为某个参数设置默认值,则必须为
它右边的所有参数提供默认值
。 - 函数定义中有默认参数,在函数实现中的函数头中可以不再写默认参数的值。
可变参数函数
1 | int sum(int n, ...); |
...
代表可以接受任意类型的数据任意多个。
获取到可变参数列表的方法
1 | int sum(int n, ...) { |
在使用va_arg宏时,要求type是POD(Plain Old Data)类型
,能用 C 的 memcpy() 等函数进行操作的类、结构体就是 POD 类型的数据,所有基本数据类型都是POD。并且如果type和对应的参数不对的话会产生强制类型转换。如果类型转换失败就会将数据设置为0或者其他初始化的值。
函数重载
函数的参数列表也称为函数特征标
函数重载要求函数的参数数目或参数类型
或参数的顺序
不同,而参数名是无关紧要,且编译器在检查时不一定
会将引用类型和本身类型视为同一特征标,但是如果调用重载函数存在二义性则编译器会报错。对于非引用传参,形参是否const是等价的
。但是当使用引用传参时,有无const是不同的
。使用指针传参时,指向const对象的指针和指向非const对象的指针做形参的函数是不同的
只是函数返回值不同不能构成函数重载
在类中,C++将区分常量和非常量函数(即函数本身是否为const)的特征标
函数重载匹配原则
- 最匹配原则
- 如果没有匹配的将会进行类型强转后进行匹配,但是进行类型强转后进行匹配后有多个匹配的会产生报错;
函数模版
函数模版并没有创建一个函数,它只是告诉编译器如何创建如何创建一个函数,编译器在遇到使用模版函数的地方会将模版函数展开成具体的函数。模版函数匹配原则:越具体越适配原则
1 | template<typename T> |
decltype(x) y
decltype(x) y,用于说明y的类型和x的类型一样,decltype的运用场景大多是模版
1 | template<typename T1, typename T2> |
函数指针
函数指针的声明方式:
1 | return_type (*pointer_name)(parameter); |
*
和pointer_name要用括号括起来,否则就变成了返回指针的函数。不能声明一个指向模版函数的指针,因为模版函数并没有实现真的函数,而只是说明如何声明函数
宏定义形式的函数
1 |
有些时候用宏定义的代码被do { } while(0);包含了起来,例如:
1 |
这是因为宏的处理是文本替换,有时候将宏用文本替换后代码就产生了语法错误,而使用do {} while(0)是为了避免由于文本替换后带来的语法错误,并保证宏函数无论如何都会执行一次。