关于引用的若干事
引用是c++中很重要的一个语法点,c++也推荐使用引用。引用继承了指针的优点,是地址层面的操作,同时它也对指针进行了一些封装,使得地址操作没有那么复杂了。
引用
对于引用最基本的解释就是:给一个变量起一个别名。也就是说两个变量名都指向同一块内存。声明变量需要注意的是:
- 声明时必须初始化
- 一旦初始化后,便不可更改
c++语法定义引用声明必须初始化,没有初始化的引用等同于野指针,是有危害性的。c++对野指针没有硬性规定但是对引用初始化有硬性规定。引用初始化后便不能改变它那个变量,也就是说一个引用只能指向一个变量,这等同于一个指针常量(指针本身不可以修改,可以通过指针修改它指向的值)。
本质
引用的基本语法决定了引用的本质实际上是一个指针常量
int b=1;
int &a=b;
以上语句等同于
int b=1;
int * const a=&b;
在调用的时候,引用可以直接修改,指针需要解引用。
引用做函数参数
引用同指针一样,诞生的意义就是作为函数参数来传递。由于引用更加简单,有些时候使用引用而不使用指针会使程序更加的简单易懂。
int swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
int main()
{
int a=0;
int b=1;
swap(a,b);
return 0;
}
初学者可能对引用能够改变实参的值比较迷惑,引用是变量的别名,使用别名和原来的名字有什么区别呢?实际上函数在传参的时完成了一个赋值的过程。也就是将实参的值赋给了形参,这样以上代码的参数传递时有如下语句实现
int &a=a; //这里的a,b代表形参和实参
int &b=b;
这样就很容易解释函数的传值调用不能改变实参的值和传引用调用能够改变实参的值。
另外需要额外注意的点就是不要把局部引用作为函数的返回值,这么做的后果和将局部变量的指针作为返回值的后果是一样的。这点不懂的同学可以了解一下有关栈的知识。
常量引用
注意:没有引用常量,因为引用本身就是常量(一经初始化,便不能更改)
常量引用描述的是不能通过这个引用修改它指向的值,常量引用的语法也十分简单,在引用的声明前加一个const就可以了。常量引用的一般使用场景就是我们需要作为函数参数传递一个值,但是我们又不想修改它,这时候我们就可以用常量引用作为形参来接受这个值。这时候初学者或许会有疑问,既然我们只想读这个变量而不是写,那么我们为何不直接传值呢?实际上这两种方法多可以达到传参数而不改变原值的目的,判断这两种方法孰优孰劣的条件就是二者谁的空间开销大,由于引用的本质是指针,所以我们在传递常量引用的时候传递的是指针,我们知道指针的占用的内存空间是8个字节,所以当我们传递的是char或者是int类型的值得时候,直接传值能节省空间的,但是当我们要传对象,结构体或者是容器的时候,最好是传递常量引用。
假如我们都传常量引用,那么相比较于传值,我们最多浪费7个字节(地址8字节减去char类型一个字节)。但是假如我们都使用传值,当我们遇到很大的结构体或者容器的时候,我们浪费的字节是将远远大于7。所以如果你嫌麻烦,在传递任何不想被修改的值的时候,可以都使用传常量引用。实际上这也是c++所提倡的。
更多相关内容查看我的个人博客:www.yhuiest.top