c++ primer plus 第六版 第八章 学习笔记

1、引用变量(&左值引用)

   1)必须在创建引用变量时对其初始化,且初始化后不能再将其作为另一个变量的引用变量;

   2)当函数的形参为引用变量时,在函数调用时即将引用形参初始化为实参,传递方式类似于地址传递,该引用变量的改变将引起原始变量的改变;

   3)函数形参为引用变量时,若传递的实参类型不匹配或者不是左值时,将创建一个类型匹配或者匿名的临时变量(同时发出警告),此时引用变量将不再指向实参而是临时变量,该临时变量只在函数调用期间存在,并且此时引用变量的变化将不会导致实参的变化;

   4)一般而言,当形参为const的引用函数时,若实参与形参的类型不匹配,系统将创建临时变量,因为此时的函数一般只用作值传递而不改变实参的值,临时变量的创建使其更通用;而当形参不是用const声明的引用变量函数时,编译器一般将会认为错误,因为此时函数一般用于改变实参的值,临时变量的创建可能导致结果不是预期的。(Visual Studio 2017 不允许创建临时变量)

   5)&&可用于右值的引用;

6)用const声明的引用传递结构时类似于值传递,不能改变原始结构的值,但采用引用的方法更节省时间和内存

7)函数形参为引用变量时,函数调用仍与普通函数相同,若有函数调用sweap(&a),(原型为void sweap(int &))则为错误的调用,函数调用时的&表示地址运算符而不是引用运算符。

2、默认参数

   1)指函数原型中,将形参列表中的一个或多个参数赋值,当调用函数时,既可以对赋值过的形参重新赋值,也可以不指定对应的实参而采用默认的参数;

2)只能在参数列表中从右到左提供默认参数,即如果为某个参数提供了默认值,则必须为参数右边所有的参数提供默认值

3)默认参数是在函数声明中体现的,函数定义与没有默认参数时完全相同,如果也在函数定义时指定默认参数,会出现“重定义默认参数“的错误;而如果只在函数定义时对其中参数指定确定值,则没有什么意义,函数与没有默认参数时一样的调用,实参值将代替定义时指定的值。

3、函数重载

多于函数特征标不同而函数名称相同的函数,在函数调用时根据实参的不同而调用不同的同名函数的功能。

  1. 函数特征标:参数列表;当多个函数的参数列表数目、类型、排列顺序均相同时,则视为其函数特征标相同。
  2. 类型引用和类型视为同一个特征标,即:double cube(double x)与double cube( double &x)不能进行函数重载,视为一个函数,特征标相同
  3. Const和非const参数视为不同的特征标,即:double cube(const double * x)与

double cube(double * x)可以发生函数重载,根据实参的类型进行函数调用。

  1. 非const参数函数也可以接受const实参,即:若只有double cube(double *x)函数,当实参为const和非const时都将调用该函数,非canst形参可以接受const和非const实参,但const形参只能接受const实参;但当有两个同名的函数参数分别为const和非const时,便只能接受与形参相同类型的实参
  2. 是特征标的不同使得可以对函数进行重载,而不是函数类型;即当函数名、特征标相同而返回值不同时,是不允许函数重载的,即:long gronk(int n)与double grank(int n)不能进行函数重载,特征标相同,不允许同时定义这样两个函数;long gronk(int n)与double gronk(float n)可以进行函数重载,因为特征标不同;即函数重载必须满足的两个要素:函数名相同,特征标不同;    
  1. 函数模板

当函数的功能相同但参数类型不同时,可以定义一个函数模板;与常规的函数时定义的异同:

  1. 其函数原型须加一行:typename(或者class)<typename T>只有T为可以自己命名的(表示参数类型),定义函数时T替换常规函数定义时的参数类型;即函数原型为:template <typename T>

            Void Swep(T &a,T&b)//Swep为函数名,括号内为参数列表

  1. 调用函数时,与常规函数调用相同,即:swep(实参列表)
  2. 函数模板并不能缩短可执行的程序,编译器将会根据实参的不同生成多个函数,再对其调用,与定义对个函数效果相同,函数模板使程序更简洁
  3. 模板函数允许非模板参数类型(泛型)的参数,即允许

Template

 <typename T>

            Void Swep(T &a,T&b,int)

  1. 模板函数也允许函数重载,即相同的模板函数名称,但是同样特征标必须不同;
  2. 模板函数并不是函数定义,当提供特定的参数使用模板函数时,编译器将自动进行隐式实例化,定义一个与提供的参数类型相匹配的函数;也可以在使用函数时进行显示实例化,告诉编译器需要定义的函数参数类型;显式与隐式实例化都是使用所定义的模板函数算法,当所需要的算法不同而函数名称以及参数与模板函数匹配时,可以进行显示具体化,重新定义一个确定参数类型的算法函数;
  3. 在编译器选择函数原型时,当函数名称、参数类型都相同时,非模板函数优于显示具体化函数优于使用模板的实例化;但当有函数调用lesser<>(m,n)时表示使用模板函数,此时即使有与其匹配的非模板函数仍编译器将选择模板函数,也可以在<>中指定要实例化函数类型;即对函数调用lesser(m,n)时非模板函数优先于模板函数,对函数调用lesser<>(m,n)限定于模板函数,此时模板函数优于非模板,且仍有模板具体化优于模板实例化;

问题:

1、&运算符:引用与地址运算符的差别,void sweap(int &a)只能表示形参为引用变量吗,还是可以表示传递的是变量a的地址;函数原型中的&表示引用,而函数调用中的&表示地址运算符。

2、函数模板问题:

Void std::swap(_Ty&,_Ty&)表示标准库中的函数,这个错误在于定义了一个与标准函数相同函数名和特征标的函数,无法进行函数重载,解决办法:更改定义的函数名;不使用标准库

猜你喜欢

转载自blog.csdn.net/Schlangemm/article/details/84174979
今日推荐