C++Primer Plus(第六版)第八章学习笔记

8.1 内联函数

关键字:inline
就是在应该放函数原型的地方直接把整个函数的定义确定,意义在于可以直接使用函数,不用跳到另一个地址去调用函数

8.2 引用变量

用&符号进行定义

int rats;
int & rodents = rats;

此处&是类型标识符的一部分,如同char*表示指向char的指针
int &表示指向int的引用

引用和指针的区别:声明引用时必须初始化,不能如指针先声明再赋值

所以引用更接近const指针

8.2.2 引用作为函数参数

用引用作为函数参数,则相当于给传入的实参进行一次引用创建,而不是普通按值传递一样创建一个副本
所以传递引用的时候可以修改原始数据

8.2.3 引用的特点

当意图为让函数使用其传递的信息而不改变其原始数据的话,应当使用常量引用
当数据比较大时使用引用更好

8.2.4 引用运用与结构

返回值用引用,可以大幅减少内存占用,普通return机制是将值复制到一个临时位置,然后将其赋值。引用就可以免去临时位置储存的内存。

8.2.5 引用运用于类

程序清单8.7
错误点:version3所指的意义是返回一个const string &类型,而在函数的设计中,返回的是一个在函数中声明的变量。所以结果是返回一个临时变量的引用。而该变量在函数结束的时候已经不存在,返回一个临时变量的引用是错误的。

8.2.6 对象继承和引用

基类引用可以指向派生类对象

8.2.7 何时使用引用参数

  • 想要修改调用函数中的数据对象
  • 传递引用而不是整个数据对象,提高运行速度
  • 传递数据较小时,用按值传递
  • 传递数组时用指针形式,当不需要修改时使用const
  • 较大的结构是使用const指针或者const引用
  • 对象为类则使用引用

8.3 默认参数

将值赋给原型中的参数,则会在调用时若不赋值就自动赋予原型中的参数,此参数就是默认参数

8.4 函数重载

关键点:函数特征标(function signature)不同,就是函数的参数类型,参数数量等。
编译器在编译的时候,会将变量与变量的引用视为同一特征标,所以仅仅是将变量变为变量的引用的重载是不被允许的。
只有特征标可以决定重载,函数类型不可以,函数类型不同但是函数名相同的话是互斥的,不叫重载。但是如果函数类型不同的同时,参数类型也不同,则是允许的

非const值赋给const变量是合法的,但是反之不合法,所以函数声明中若参数是const型,则用非const变量作为实参,就相当于在函数运行时创建一个临时的const变量,将非const变量赋值进去,所以是合法的。

8.5 函数模板

函数模板就是用泛型来定义函数(参数化类型/parameterized types),其中函数的参数类型可以使用具体的类型替换,通过将类型作为参数传给模板,可是编译器生成该类型的函数。

template <typename AnyType>
void Swap(AnyType &a, AnyType &b)
{
AnyType temp;
temp = a;
a = b;
b = temp;
}

关键字template和typename是必需的,除非可以用关键字class代替typename。
使用的时候只需要在原型出声明函数,在程序体中使用是可以直接使用幂函数会自己声明对应参数类型的函数,就像无线重载过的函数。

8.5.1 重载的模板

和函数的重载相似,就是特征标不同。

8.5.2 模板的局限性

对于某些类型,模板不能做到一招吃遍天下

8.5.3 显示具体化

1.第三代具体化(ISO/ANSI C++标准)

  • 对于给定的函数名,可以有非模板函数,模板函数和显示具体化模板函数以及他们的重载版本
  • 显示具体化的原型和定义应以template<>开头,并通过名称来指出类型
  • 具体化优先于常规模板,而非模板函数优先于具体化常规模板

8.5.4 实例化和具体化

隐式实例化,显示实例化,显示具体化统称为具体化(specialization),表示类型都是用具体类型的函数定义,而不是通用描述

而现实实例化在template后不包含<>,显示具体化要包含。用法其实就这一点点区别

template void Swap<int> (int ,int) //explicit instantiation
template <> void Swap<int>(int& , int&) //explicit specialization

8.5.5 编译器选择使用哪个函数版本

这个选择过程叫做重载解析(overloading resolution),大概流程

1. 创建候选函数列表,包含被调用函数名称相同的所有函数
2. 使用候选函数列表创建可执行函数列表,这些都是参数数目正确的函数,为此有一个隐式转换序列,其中包括实参类型和相应的形参类型完全匹配的情况。
3. 确定是否有最佳可执行函数,如果有则调用,没有则报错

在具体操作时,先看特征标,个数不同的先排除。然后是看整个函数将调用参数与候选函数参数的匹配所要进行的转换,优劣顺序如下

1. 完全匹配,但是常规函数优先于模板。
2. 提升转换
3. 标准转换
4. 用户定义转换

当有两个完全匹配符合时,是一个错误,不过有两个例外。指向非const数据的引用和指针优先与非const指针和引用参数匹配

8.5.6 模板函数的发展

关键字decltype(C++11)

int x;
decltype(x)y ;		//make y the same type as x
//所以在不知道具体计算结果类型的模板中,可以使用
decltype(x+y) xpy = x+y;
//若要多次声明,则结合typedef一起使用,将这种类型转换操作设为一个类
//最后一点,后置返回类型
auto h(int x,float y) -> double;

猜你喜欢

转载自blog.csdn.net/baidu_29452653/article/details/88123291
今日推荐