C++ Primer Plus 三
1.函数指针
double pam(int);
double (*pf) (int);
pf=pam;
double x=pam(6);
double y=(*pf)(6);//通过
double yy=pf(5);//通过
历史和逻辑:
为何pf和(*pf)等价呢?一种学派认为,由于pf是函数指针,而*pf是函数,因此应将(*pf)()用过函数调用。另一种学派认为,由于函数名是指向该函数的指针,指向函数的指针的行为应与函数名相似,因此应将pf()用作函数调用使用。C++进行了折衷--这两种方式都是正确的,或者至少是允许的,虽然他们在逻辑上是相互冲突的。在认为折衷折衷粗糙之前,应该想到,容忍逻辑上无法自圆其说的观点正式人类思维活动的特点。
2.内联函数
在C++中,为了解决一些频繁调用的小函数大量消耗栈空间或者叫栈内存的问题,特别的引入了inline修饰符,表示为内联函数。
栈空间:就是指安放程序的局部数据也就是函数内数据的内存空间,在系统下,栈空间是有限的,如果频繁的大量的使用就会造成因栈空间不足所造成的程序出错的问题,函数的死循环递归调用的最终结果就是导致栈内存空间枯竭。
声明内联函数:
inline string Test(int a);//函数原型声明为inline,即:内联函数
内联函数实现:
string Test(int a)
{
return (a%2==0)?"偶数":"奇数";
}
如果函数定义占用多行,则将其作为内联函数就不太合适。
关于内联与宏:incline工具是C++新增的特性。C语言使用预处理器语句#define来提供宏--内联代码的原始实现。
#define SQUARE(X) X*X
这并不是通过传递参数实现的,而是通过文本替换来实现的--X是"参数"的符号标记。
a=SQUARE(5.0): is replaced by a=5.0*5.0
b=SQUARE(2+3): is replaced by b=2+3*2+3
3.尽可能多得使用const
将引用参数声明为常量数据的引用的理由有3个:
1>.使用const可以避免无意中修改数据的变成错误。
2>.使用const使函数能够处理const和非const实参,否则将只能接受非const数据。
3>.使用const引用使函数能够正确生成并使用临时变量。
因此,应尽可能将引用形参声明为const。
4.何时使用引用参数
* 程序员能够修改调用函数中的数据对象。
* 通过传递引用而不是整个数据对象,可以提高程序的运行速度。
当数据对象比较大时(如结构和类对象),第二个原因最重要。这些也是使用指针参数的原因。这是由倒立的,因为引用参数实际上是基于指针的代码的另一个借口。那么,什么时候应使用引用、什么时候应使用指针呢?什么时候又应按值传递呢?下面是一些指导原则:
对于使用传递的值而不作修改的函数:
* 如果数据对象很小,如内置数据类型或小型结构,则按值传递。
* 如果数据对象是数组,则使用指针,因为这是唯一的选择,并将指针声明为指向const的指针。
* 如果数据对象是较大的结构,则使用const指针或const引用,以提高程序的效率。这样可以节省赋值结构所需的时间和空间。
* 如果数据对象是类对象,则使用const引用。类设计的语义常常要求使用引用,这是C++新增这项特性的主要原因。因此,传递类对象参数的标准方式是按引用传递。
对于修改调用函数中数据的函数:
* 如果数据对象是内置数据类型,则使用指针。如果看到诸如fixit(&x)这样的代码(其中x是int型),则很明显,该函数将修改x。
* 如果数据对象是数组,则只能使用指针。
* 如果数据对象是结构,则使用引用或指针。
* 如果数据对象是类对象,则使用引用。
5.关于函数重载、函数模板和函数模板重载选择策略
1>.创建候选函数列表。其中包含与调用函数的名称相同的函数和模板函数。
2>.使用候选函数列表创建可行函数列表。
3>.确定是否有最佳的可行函数。如果有,则使用它,否则该函数调用出错。
调用函数顺序:
1>.完全匹配,但常规函数优先于模板。
2>.提升转换(例如,char和shorts自动转换为int,float自动转换为double)。
3>.标准转换(例如,int转换为char,long转换为double).
4>.用户定义的转换,如类声明中定义的转换。
6.重载解析将寻找最匹配的函数。如果只存在一个这样的函数,则选择它;如果存在多个这样的函数,但其中只有一个是非模板函数,则选择该函数;如果存在多个适合的函数,并且他们都为模板函数,但其中有一个函数比其他函数更具体,则选择该函数。如果有多个同样合适的非模板函数或模板函数,但没有一个函数比其他函数更具体,则函数调用将是不确定的,因此是错误的;当然,如果不存在匹配的函数,则也是错误。
7.数据存储持续性
自动存储持续性:在哈数定义中声明的变量(包括函数参数)的存储持续性为自动的。他们在程序开始执行器所属的函数或代码块时被创建,在执行完函数或代码块时,他们使用的内存被释放。
C++有两种存储持续性为自动的变量。
静态存储持续性:在函数定义外定义的变量和使用关键字static定义的变量的存储持续性都为静态。他们在程序整个运行过程中都存在。C++有三种存储持续性为静态的变量。
动态存储持续性:用new操作符分配的内存将一直存在,直到使用delete操作符将其释放或程序结束为止。这种内存的存储持续性为动态,又是又称为自由存储。