c++ Primer Plus(第八章)

第八章

1.内联函数

  • 在函数声明前加上inline
  • 在函数定义前加上inline
  • 虽然请求为内联函数,但是不一定编译器使用,比如函数递归或者函数过大

2.引用变量

  • 引用变量需要在声明时定义,否则报错,并且捆绑后,不能解绑,类似与const指针
  • 引用变量作为函数参数传入时候,必须是变量,否则报错,比如f(a+3);//错误 (f(int &))

3.临时变量,引用参数,const

  • 如果实参与引用参数不匹配,将会生成临时变量,c++11以后只有const引用才会,但之前的不是这样(也就是说,如果不匹配,尽管是引用,但是实际函数传入的型参是经过转化后的匿名参数,和原来没有关系,你如果改变了临时参数也不影响原来的实参)

  • 左值 左值是指可以可被引用的数据对象,非左值包括:字面常量(常量字符串,7,4.2等字面量),以及包含多项的表达式

  • const引用创建临时变量的情况

    +  实参类型正确,但不是左值
    +  实参类型不正确,但可以被转换 
    
  • 函数定义形参有const使函数能够处理const和非const实参,否则只接受非const

  • c++新增右值引用,这种引用可指向右值(非左值),比如int && =2.0* j
    +
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>
using std::cout;
using std::endl;
int f(const int&);
int main()
{
//int& a=10;不能是字面量
int j=10;
//int& a=j*10;不能是表达式
//long& a=j;新标准c++中非const引用不支持转换
const long& a=j;
f(a);
cout<<a<<endl;

}
int f(const int& a)
{
int b=a;
return 0;
}

4.引用做返回值

  • 确保返回的引用所绑定的变量不是临时变量
  • 返回引用的函数是左值,及可以放在等号左边,然后传统的返回却不行

5.默认参数

  • 对于带参数的函数,必须从右向左添加默认值。也就是说,要为某个参数设置默认值,必须为他右边的所有参数提供默认值(否则产生二义性)

6.函数模板

+在函数前面加 template <typename(class) Anytype> Anytype是指程序员自己定义的名字

  • 模板函数的调用为 f();(显示调用),实例化
    +f();隐式调用

7.模板重载

  • 和常规函数重载一样,带模板的函数重载需要其特征不同
1
2
3
4
5
template <class T>
void Swap(T& a,T& b);//origin

template <class T>
void Swap(T a[],T b[]);//new

8.为特定类型提供具体化的模板定义

  • 对于给定的函数名,可以右非模板函数,模板函数和显示具体化模板函数以及他们的重载版本
  • 显式具体化的原型和定义应为template<>打头,并通过名称指出类型
  • 显示具体化优先于常规模板,而非模板函数优先于显示具体化
  • 显示具体化的使用 :tempale<> void swap<int>(int,int) 使用template 代表这是一个int的具体化,参数表以及表明了,所有可以不写

9.显式具体化与显式实例化

  • 使用template void f<int>()表示显式告诉编译器实例化具体的函数,也是一种声明,但是告诉了编译器,编译器不用再推导,同时,同一文件不能同时显式实例化和具体化同一类型函数,并且某些编译器不支持这一用法

10.编译器使用函数的版本

  • 当有多个模板匹配的时候,编译器会选择一个最佳方式进行匹配,如果不存在,会返回一个二义性的错误
  • 指向const的指针和数据优先于非const的,非模板函数优先于模板
  • 两个完全匹配的模板函数,较具体化的模板函数优先 ,即f(T a),f(T * a) 后者会优先匹配,偏特化必须是相对于T的,即指明T的一部分特性,T* 指明是指针
  • 寻找最佳的过程被称之为重载解析