1.引用和指针的关系
引用在语法层面上不开辟新的空间,是对变量或别名取别名,我们对别名进行的任何操作也会同样作用于变量本身,这和形参有本质的区别,它的功能更像是指针。事实上,引用底层的实现就是指针,它们没有区别,都会开辟空间。并且它们的效率也完全一致。
在计算char&的大小时,会按照char&指向的对象的大小来计算,因此是1而不是指针的大小。
但是在C++中,引用并没有办法替代指针,因为引用没有办法改变它指向的对象,所以在如p = p->next;等常见的指针操作都没办法使用
指针允许空指针的存在,而引用不存在空引用,指针相对而言更加灵活,引用相对而言更加安全。
但引用的安全并不是绝对的,如果引用的指针存在越界的情况,语法层面也无法检测出来。
2.引用权限放大缩小问题
引用作为一种对变量取别名的用法,对别名和本体的访问权限必须一致,有的情况下比较容易出错。
所有表达式的值都会先存放在一个临时变量里,如果有变量接收就把这个值赋过去,如果没有就抛弃这个值。这个临时变量是只读的,所以如果要对表达式的返回值取别名,只能是只读操作。
权限的缩小可行,但不能对只读的别名进行操作
权限的放大,主要是在有const的情况下要注意
注意甄别权限的放大,有的情况下只是赋值操作,不存在放大的情况
3.内联函数的运用
内联函数是C++中对宏函数的一种替换。宏函数的书写过于复杂而且极易出现错误。因此,在代码量少且调用频繁的情况下,使用内联函数是一种更优的选择。
swap这个函数在这里就直接被展开了,这样的程序就会省去开辟函数栈帧、销毁栈帧的时间。同时内联函数的书写更为直观,宏函数。
但是内联函数(inline)只是对编译器的一个建议,因为如果一个函数有成百上千代码,而这个函数被数百次调用,那么在预处理阶段被展开的代码量是极为恐怖的,所以为了防止这种事情发生,当函数的代码数达到一定级别时,inline就会失效。
这里可以看到,当代码量增加到一定程度,这个内联函数就不会展开,就当成正常函数使用,这个时候的开支也一定是最合理的。
Debug调试设置:
4.auto类型的使用
注意在函数定义时不能使用auto类型,这也是一种规范化的规定,因为如果auto被允许,相当于任何类型的数据都可以作为形参,函数的功能实现也会受到影响。
返回值可用auto
可以对auto进行一些修饰,如auto&,auto*,表示只能推导引用或指针类型。
auto主要的作用是简化长类型,防止使用过于复杂,如函数指针
这里也能看出后面两种写法比第一种更加简洁。
但是auto还是要慎用,因为用多了之后就不清楚对应的变量的类型了。
要查看auto推导的类型,可以使用typeid(a).name(),typeid也是关键字,类似于typedef
5.范围for使用
范围for只能针对数组,指针(包括数组指针)、字符等都不行
表示方式:for (type x : arr)
for(auto x : arr)从前到后遍历数组时自动++,将arr里面的值依次赋给x,因为x是临时变量,所以直接修改x并不会影响数组。要修改x指向的数组的值,可以使用for(auto& x : arr),这相当于对数组里面的内容取别名,再在后面的代码中对x操作就可以影响数组的值