本部分罗列了本章的难点或注意点,以便复习巩固或者回忆,关注私聊我可以免费领取pdf版C++ Primer Plus 第6版。
-
编写宏define可能不能正确工作,考虑使用内联函数inline
#define SQUARE(X) X*X a = SQUARE(4.5+7.5) //4.5+7.5*4.5+7.5
-
要使用内联函数知识在函数声明或者定义时加上关键字inline。通常省略原型,直接去定义。
-
必须在声明引用时为其初始化。int & a=b; 其实引用是int * const c= &d;的伪装表示。 a==*c;
-
//初始化便设置好引用,不能变动 int rates = 101; int * pt = &rates; int & a = *pt; int bun = 50; pt = &bun; cout << a;//101
-
左值参数是可被引用的数据对象。例如变量、数组元素、结构成员、引用和解除引用的指针。 想在,常规变量和const变量都可视为左值。但const输入不可修改的左值。
-
临时变量生成条件:1.实参的类型正确,但不是左值。2实参的类型不正确,但可以转换成正确的类型。
-
临时变量会影响值的交换
int swap (int &,int &); long a = 3,b =5; swap(a,b); //不交换值
-
右值引用&&
-
返回引用时应注意避免返回一个指向临时变量的引用,也要避免返回指向临时变量的指针。
-
返回引用可以选择返回调用函数时的数据或者使用new。
-
使用引用能够修改调用函数中的数据对象,通过传递引用可以提高程序的运行速度。
-
数组没有引用。
-
对于带参数列表的函数,必须从右向左添加默认值。实参从左到右依次赋值,不能跳过。
-
引用不能作为函数重载的区别。
-
const也可以用作重载。匹配函数时不区分const和非const变量。会根据实参是否为const选择使用哪个。
void dribble(char *) { cout << "s"; } void dribble(const char *) { cout << "a"; }
-
重载是以特征标,也就是参数列表为根据的,不是函数类型使得函数可以进行重载。
-
重载引用参数 (会根据参数是左值、const还是右值来确定)
void stove(double &r1); //与可修改的左值匹配 void stove(const double &r2); //与可修改的左值、const左值参数和右值参数匹配 void stove(double && r3); //与右值匹配 double x=55.6; const double y = 32.0; stove(x); //匹配1 stove(y); //匹配2 stove(x+y);//匹配3 如果没有3,也可以匹配2
-
模板具有局限性,可能无法处理某些类型。
-
当有多个原型,编译器选择模型时,非模板版本优于显示具体化优于模板版本
-
模板并未定义函数,当函数被调用使编译器定义函数。
-
隐形实例化 显示实例化 和显示具体化
//隐形实例化在调用模板函数时创建实例 template void Swap<int>(int,int); //显示实例化 使用模板直接命令编译器创建特定的实例 template <> void Swap<int>(int &,int &)//显示具体化 不使用模板来生成函数定义,显示地定义函数定义
-
试图在同一个文件中使用同一种类型的显示实例和显示具体化将出错
-
重载解析
1.完全匹配,但常规函数优于模板
2.提升转换
3.标准转换
4.用户定义的转换
-
一般出现两个函数完全匹配是一种错误。但有两种例外。1.const和非const数据。非const数据会与非const形参的函数匹配。2.一个是非模板函数,一个不是。非模板函数有限与模板函数(包括显示具体化),如果都是模板函数,较具体的优先。
-
找出最具体的模板规则叫做函数模板的部分排序规则
-
(c++11)关键字decltype 解决了模板中无法处理两个不同的类型相加
int x; decltype(x) y; //make y the same type as x template <class T1,class T2> void ft(T1 x,T2 y){ ... decltype(x+y) xpy = x+y; ... }
-
decltype(expression) var;
第一步:如果expression是一个没有用括号的标识符,则var的类型与该标识符类型相同;
第二步:如果expression是一个函数调用,则var的类型与函数的返回类型相同;
第三步:如果expression是一个左值,则var为指向其类型的引用。(也要有括号);
第四步:前面条件都不满足,则var与expression类型相同。
double x = 5.5; decltype(x) w; //w is type double long indeed(int); decltype(indeed(int)) m; //m is type long double xx = 4.4; decltype((xx)) r2 = xx; //r2 is double & int j = 3; decltype(j+3) i; //i is type int
-
(c++11)新增声明语法 解决了模板函数返回值类型不明的情况
template<class T1,class T2> auto gt(T1 x,T2 y) -> decltype(x+y) { ... return x+y; }