1、函数探幽第八章 函数探幽记住:arri = *(arr + i) &arri = arr + i 8.1 内联函数(inline) (使用范围:执行代码较短)使用方法: 在函数声明前加上inline 在函数定义前加inline内联与宏内联函数是通关过传递参数来实现的,宏(#define)是通过文本替换来实现的。注意:如果使用C语言的宏执行了类似函数的功能,应考虑将他们转换为C+内联函数。8.2 引用变量8.2.1创建引用变量Int rats;Int& rodents = rats; rodents是rats的引用(他们指向相同的值和相同的内存单元)Int* prats = &rats; 创建指
2、向rats的指针引用与指针的差别 声明引用时将其初始化,不能像指针先声明在赋值。(通过初始化声明来设置引用,不能通过赋值来设置) 引用更加接近于const指针,int& rodents = rats; int* const pr = &rats;8.2.2将引用作为函数参数(按值传递/按引用传递)Void sneezy(int *p);Int main() Int times = 20; Sneezy(×);Void sneezy(int *p)注;swap(int& a, int& b) / int temp; temp = a; a = b; b = temp;Swap(int*
3、 a, int* b); /int temp; temp = *a; *a = *b; *b = temp;Swap(int a, int b); / int temp; temp = a; a = b; b = temp; 失败,复制的副本临时变量、引用参数和const有名称和类型的数据对象,才可以为其创建引用,而不需要临时变量。(参数必须是const引用)实际上,对于形参为const引用的C+函数,如果实参不匹配,其行为类似于按值传递。应该尽可能的使用const引用右值引用(C+11):引用后面可以是字面常量或者多项式表达式Double& rref = std:sqrt(36.0);Dou
4、ble j = 15;Double& jref = 2.0*j + 18.5;Std:cout rref n;Std:cout jref ct) Ct=digits-ct; While(ct-) Num/=10; Return num; Else Return numChar* left(const char* str, int n) if(n0) n=0; Char* p = new charn+1; Int i; For (i=0;in & stri; i+) Pi=stri; While(i=n) Pi+ = 0; Return p;8.5 函数模板(对不同类型使用同一种算法的时候,可以
5、使用模板)Template typename可以换成class;Void swap( anytype &a, anytype &b) Anytype temp; Temp = a; A = b; B = temp;重载的模板(模板的特征标不同)templatevoid swap(T &a, T &b);templatevoid swap(T *a, T *b, int n );模板的局限性:编写的模板函数无法处理某些类型。 运算符重载,用于特定的结构或者类(第11章) 为特定类型提供具体化的模板定义(本章介绍这种解决方案)8.5.1 显示具体化(编译器找到与函数调用匹配的具体化定义时,将使用该
6、定义而不再寻找模板)对于给定的函数名,可以有非模板函数、模板函数和显示具体化模板函数以及重载版本。优先级:非模板函数=具体化函数=常规模板TemplateVoid swap(T&, T&);Void swap(job&, job&);Template void swap(job&, job&) 显示具体化模板函数Template void swap(job&, job&) 简化版本Template void swap(char&, char&) 显示实例化模板函数8.5.2 实例化和具体化(注意区别:显示实例化和具体化)函数模板本身不是函数定义,编译器在使用特定类型的函数模板时候,才会生成函数
7、定义,得到的是模板的实例。称为隐式实例化。C+允许显示实例化:swap(); 声明:Template void swap(int, int);显示具体化的函数声明为:(不需要通过函数模板来生成还是定义,而应该使用专门为int类型显示的函数定义)Template void swap(int &, int &);Template void swap(int &, int &);隐式实例化、显示实例化、显示具体化 统称为具体化。8.5.3 编译器使用哪个函数版本确定哪个函数更好的时候,从最佳到最差的顺序如下所述:详细见第三章:char 到 float转换属于 标准转换。当出现两个函数均完全匹配的时候
8、就会出现错误,这一规则有两个例外:1 完全匹配和最佳匹配注:type(argument-list)意味着用作实参的函数名与用作形参的函数指针只要类型和参数列表相同,就是匹配的。问题:这边究竟模板1具体还是模板2具体?(这边解释感觉前后矛盾)分析的结果感觉应该是模板2。2 部分排序规则示例(总结)3. 创建自定义选择8.5.4 模板函数的发展(C+98到C+11)C+11中的关键字 decltype用这个关键字来推算出类型。TemplateVoid ft(T1 x, T2 y) Decltype(x+y) xpy = x+y;Decltype比这些实例演示要复杂一些。为确定类型,编译器必须遍历一
9、个核对表,简化版如下: 如果expression是一个没有用括号括起的标识符。则var的类型与该标识符类型相同。double x = 5.5; double& rx = x; decltype(x) w; (w类型为double) decltype(rx) y;(y的类型为double&) 如果expression是一个函数的调用,则var的类型与函数的返回类型相同。Long indeed(int); decltype(indeed(3) m; (m的类型为int) 如果expression是左值则var为指向其类型的引用。(用括号括起来的标识符 )double xx = 4.4; declt
10、ype(xx) r2 = xx;(double&) decltype(xx) w = xx;(double) 如果上述类型全都不满足则var类型与expression的类型相同。int j = 3;decltype(j+6) i1; i1是int类型另外一种函数声明语法(C+后置返回类型)Double h(int x, float y);Auto h(int x, float y)-double; 被称为后置返回类型(auto与decltype结合起来)TemplateAuto gt(T1 x, T2 y) - decltype(x+y) . Return x+y;TemplateVoid ft(T1 x, T2 y ?type? xpy = x + y; 注:可以将?type?换为decltype(x+y)x,y均有作用域,可以使用decltypeTemplate?type? ft(T1 x, T2 y return = x + y; 注:不可以将?type?换为decltype(x+y)x,y不在作用域内,不可以使用decltype,应该将auto与decltype结合起来。如上面所示
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1