1.局部静态对象:
某些时候,有必要令局部变量的生命周期贯穿函数调用及之后的时间,可以将局部变量定义成static类型从而获得这样的对象。局部静态对象在程序的执行路径第一次经过对象定义语句时初始化,并且直到程序终止才被销毁,在此期间即使对象所在的函数结束执行也不会对它有影响。
如果局部静态变量没有显示的初始化,它将执行值初始化,内置类型的局部静态变量初始化为0。
2.和其他的名字一样,函数的名字也必须在使用之前声明。类似于变量,函数只能定义一次,但可以声明多次。如果一个函数永远不会被我们用到,那么它可以只有声明没有定义。
函数的声明和函数的定义非常类似,唯一的区别是函数声明无需函数体,用一个分号代替即可。
3.参数传递
每次调用函数时都会重新创建它的形参,并用传入的实参对形参进行初始化。(形参初始化的机理与变量初始化一样)
和其他变量一样,形参的类型决定了形参和实参交互的方式。如果形参是引用类型,它将绑定到对应的实参上;否则,将实参的值拷贝后赋给形参。
4.使用引用避免拷贝
拷贝大的类类型对象或容器对象比较低效,甚至有的类类型根本就不支持拷贝操作。当某种类型不支持拷贝操作时,函数只能通过引用形参访问该类型的对象。
如果函数无需改变引用形参的值,最好将其声明为常量引用。
5.递归
如果一个函数调用了它自身,不管这种调用是直接的还是间接的,都称该函数为递归函数。
6.函数重载
如果同一个作用域内的几个函数名字相同但形参列表不同,我们称之为重载函数。
执行这些函数时,编译器会根据传递的实参类型推断想要的是哪个函数。
不允许两个函数除了返回类型外其他的要素都相同。假设有两个函数,它们的形参列表一样但是返回类型不同,则第二个函数的声明是错误的。
顶层const不影响传入函数的对象,一个拥有顶层const的形参无法和另一个没有顶层const的形参区分开来。
7.如果我们在内层作用域中声明名字,它将隐藏外层作用于中声明的同名实体。在不同的作用域中无法重载函数名。
一旦在当前作用域中找到了所需的名字,编译器就会忽略掉外层作用域中的同名实体,剩下的工作就是检查函数调用是否有效了。(c++中名字查找发生在类型检查之前)
8.默认实参
一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值。
如果我们想使用默认实参,只要在调用函数时省略该实参就可以了。
函数调用时实参按其位置解析,默认实参负责填补函数调用缺少的尾部实参(靠右侧位置)。
函数声明习惯放在头文件中,且一个函数只声明一次,但是多次声明统一个函数也是合法的。不过有一点需要注意,在给定的作用域中一个形参只能被赋予一次默认形参。换句话说,函数的后续声明只能为之前那些没有默认值的形参添加默认形参,而且该形参右侧的所有形参必须都有默认值。
局部变量不能作为默认实参。除此之外,只要表达式的类型能转换成形参所需的类型,该表达式就能作为默认实参。
9.内联函数
调用函数一般比丘等价表达式的值要慢一些,一次函数调用其实包含着一系列工作。
将函数指定为内敛函数,通常就是将它在每个调用点上内联地展开,从而消除了函数运行时的开销。
在函数的返回类型前面加上关键字inline,这样就可以将它声明成内联函数了。
一般来说,内敛机制用于优化规模较小,流程直接,频繁调用的函数。
10.constexpr
constexpr函数是指能用于常量表达式的函数,定义constexpr函数的方法与其他函数类似,不过要遵循几项约定:函数的返回类型及所有形参的类型都得是字面值类型,而且函数体中必须有且只有一条return语句。
11.asseert预处理宏 p215
NDEBUG预处理变量p216