C++学习笔记2:函数探幽

xiaoxiao2021-02-28  156

《C++ Primer Plus》第八章:函数探幽

1.内联函数

1.1 内联函数机制

常规函数将程序流程转到独立的函数,内联函数用内联代码替换函数调用。内联函数的运行速度比常规函数稍快,但占用更多内存。如果在程序的10个地方调用了同一个内联函数,则该程序将包含该函数代码的10个副本。

1.2 语法

使用关键字inline,通常省略原型,将整个定义放在本应提供函数原型的地方

inline double square(double x){return x*x;}

2. 引用变量

2.1 创建引用变量

int rats; int & rodents = rats; rodents作为rats的别名,它们指向相同的值和内存地址。声明引用时必须将其初始化,之后不能再对其赋值。

2.2 将引用用作函数参数

一般用于结构和类。

2.3 引用的属性和特点

double cube(double a){return a*=a*a;} double refcube(double & a){return a*=a*a;} double refbuc1(const double & a){return a*a*a;} double x = 4.0; double re1 = cube(x+5); double re2 = refcube(x+5); //wrong double re3 = refcube(x+5); //create temporary variable 如果想让函数使用传递给它的信息,而不对这些信息进行修改,同时又想使用引用,则应使用常量引用。

对传递给引用参数的实参类型限制比较严格,如上代码,不能将表达式传递给引用参数。

但如果是常量引用参数,将生成临时变量。

2.4 返回引用

返回引用时不需要先将结果复制到一个临时位置,再将结果复制给接收返回结果的变量,而是直接将结果复制到接收返回结果的变量。

注意:避免返回函数终止时不再存在的内存单元引用,一般返回一个作为参数传递给函数的引用,或者用new来分配新的存储空间。如下代码。

const double & clone1(double & ft) { double re; re = ft; return re; } const doubel * clone2(double & ft) { double * re; *re = ft; return *re; }

3. 默认参数

对于带有参数列表的函数,要为某个参数设置默认值,则必须为它右边的所有参数提供默认值。因为实参按从左到右的顺序依次赋给相应的形参,而不能跳过任何参数。只有函数原型指定默认值,函数定义与没有默认参数时完全相同。

4. 函数重载

4.1 定义

函数的参数列表(特征标)相同,即参数数目、类型、排列顺序相同,则为函数重载。

4.2 注意

编译器在检查特征标时,将类型引用和类型本身视为同一个特征标。

是特征标而不是函数类型使得可以对函数进行重载,如下两个声明是互斥的。

long gronk(int n,float m); double gronk(int n,float m);

5. 函数模板

5.1 语法

在标准C++98添加关键字typename之前,C++使用关键字class创建模板。现在使用typename和class均可。

并非所有的模板参数都必须是模板参数类型。

一般讲函数模板放在头文件中,在需要使用函数模板的文件中包含头文件。

template void swap(T & a,T & b) { T temp; temp =a; a = b; b = temp; } template void swap(T & a,T & b) { T temp; temp =a; a = b; b = temp; }

5.2 显示具体化

编写的函数模板很可能无法处理某些类型,为这些类型编写的函数模板的具体版本为显示具体化。 编译器在选择原型时,非模板版本>显示具体化>函数模板。 struct job { char name[40]; double dalary; int floor; }; void swap(job &, job &); template void swap(T &, T &); template <> void swap (job &, job &); //显示具体化方法一 template <> void swap(job &, job &); //显示具体化方法二

5.3 显示实例化

在代码中包含函数模板本身不会生成函数定义,编译器使用模板为特定类型生成函数定义时,得到的是模板实例。模板的实例化分为隐式实例化和显示实例化。 template void swap(T &, T &); swap(a,b); //隐式实例化 template void swap (a,b); //显示实例化

5.4 关键字decltype

如下代码中a+b的类型无法确定,只知道跟(a+b)的类型相同。 template void ft(T1 a,T2 b) { ... decltype(x+y) xpy = x + y; ... } 关键字decltype表示变量var的类型和括号中的expression的类型相同。注意:如果expression是由括号扩起的标识符,则var为指向其类型的引用。 decltype (expression) var;

5.5 C++11后置返回类型

auto h(int x,float y) ->double {/*function body*/}; template auto get(T1 x,T2 y) ->decltype(x+y) { ... return x+y; }

转载请注明原文地址: https://www.6miu.com/read-19072.html

最新回复(0)