6.1 函数基础
1.局部静态对象 static类型
在程序的执行路径第一次经过对象定义语句时初始化,并且直到程序终止才被销毁。
没有显示初始值的局部静态变量执行值初始化,内置类型的局部静态变量初始化为0。
6.2 参数传递
1.尽量使用常量引用
如果函数无须改变引用形参的值,最好声明为常量引用。
2.const形参
当形参有顶层const时,传给它常量对象或者非常量对象都是可以的:
void fcn(const int i) {/* fcn能够读取i,但是不能向i写值*/ }
调用fcn函数时,既可以传入const int 也可以传入 int。
3.数组形参
void print(const int*); //三种等价形式,每个函数都有一个const int*类型的形参
void print(const int[] );
void print(const int[10] ); //这里的维度表示我们期望数组含有多少元素,实际不一定
6.3 返回类型和return语句
1.函数返回引用
如果函数返回引用,则该引用仅是他所引对象的一个别名。
const string &shorterString(const string &s1, const string &s2)
{
return s1.size() <= s2.size() ? s1 : s2;
}
其中形参和返回类型都是const string的引用,不管是调用函数还是返回结果都不会真正拷贝string对象。
2.引用返回左值
调用一个返回引用的函数得到左值,其他返回类型得到右值。
3.返回数组指针的几种方法
(1)类型别名
typedef int arrT[10]; //arrT是一个类型别名,它表示的类型是含有10个整数的数组
using arrT = int[10]; //arrT的等价声明
arrT* func(int i); //func返回一个指向含有10个整数的数组的指针
(2)正常声明
返回数组指针的函数形式如下:
Type (*function (parameter_list) ) [dimension]
如:int (*func(int i) ) [10]
(3)尾置返回类型
尾置返回类型跟在形参列表后面并以一个->符号开头,在本该出现返回类型的地方放置一个auto
如: auto func(int i) -> int(*) [10];
(4)decltype
适用于知道函数返回的指针将指向哪个数组
例子如下:
int odd[] = {1, 3, 5, 7, 9};
int even[] = {0, 2, 4, 6, 8};
decltype(odd) *arrPtr(int i)
{
return (i % 2) ? &odd : &even; //返回一个指向数组的指针
}
6.4 函数重载
1.重载的函数应该在形参数量或形参类型上有所不同。
2.main函数不能重载。
3.如果形参是某种类型的指针或引用,则通过区分其指向的是常量对象还是非常量对象可以实现函数重载,此时const是底层的。
4.当我们传递一个非常量对象或者指向非常量对象的指针时,编译器会优先选用非常量版本的函数。
5.在不同的作用域中无法重载函数名。
6.5 特殊用途语言特性
1. 默认实参
- 一旦某个形参被赋予了默认值,其后所有形参都必须有默认值。
- 函数调用时实参按其位置解析,默认实参负责填补函数调用缺少的尾部实参。
- 在给定的作用域中一个形参只能被赋予一次默认实参。
- 表达式可以作为默认实参。
2. 内联函数
在函数返回类型前面加上关键字inline,即可声明成内联函数。
3. constexpr函数
constexpr函数指能用于常量表达式的函数。其返回类型及所有形参的类型都得是字面值类型,且函数体中必须有且只有一条return语句。
constexpr函数被隐式地指定为内联函数。
其函数体内也可以包含其他语句,只要这些语句在运行时不执行任何操作。