1.引用
c++的引用,其实是一个变量的别名:
引用的定义:
int a = 10;
int& b = a;
使用一个&符号,这里不是取地址的意思,而是表示b变量是a 的引用,也就是表示b是a的别名。在内存空间中,a 和 b表示的是同一个地址。
引用必须在定义的时候就初始化,不允许这样定义:
int a = 10 ;
int& b;
b = a;
这是一个极其错误的写法,引用不允许这样定义。
引用自身引用的变量不可修改:比如:
int a = 10;
int& b = a;
int c = 20;
b = c;
这样的写法,其实是将c变量的值赋值给b,并且b是a 的别名,所以就相当于赋值给a,而不是让b成为c变量的别名。这就是引用一旦被定义,就不可修改
由于引用必须在定义的时候对其初始化,所以没有所谓的空引用,这一点和指针区别很大!
并且,没有所谓的二级引用或者说多级引用:
int a = 0;
int& b = a;
int&& c = b //这是一个错误的做法,引用只有一级,没有多级引用
引用是一个变量的别名,在内存空间中他俩代表着同一块地址,所以一旦修改引用的值,原来变量的值也会被修改,反之亦然。
2.引用与const的结合
引用与const的结合要比与指针结合简单得多
(const与指针的结合在我以前的博客中提到过)
由于引用自身不可修改,所以就只有一种结合方式:
int a = 10;
int& b = a;
const int& b = a;
const int c = 20;
//int& d = c; 错误!
const int& d = c;
当引用的变量是普通变量是,使用常引用或者普通引用都可以,常引用只是不能通过引用来修改变量的值。
但是当引用的变量位常量或者常变量时 , 就必须使用常引用。因为变量自身不可被修改,定义普通引用,就出现了歧义,可以通过引用来修改变量的值。
const int& t = 10;
const string& str = "hello";
这种常引用,其中对字符串的引用和c语言中const char* str="hello"类似,对于常量来说,必须使用常引用!
右值引用:
int&& b = 10;
它的底层其实就是常引用
3.指针与引用的关系
从语法层面上来看:
1.指针保存的时变量的地址,而引用是变量的别名;
2.系统会给指针分配空间,但是却不给引用分配(因为引用和变量本身代表着同一块地址空间)
3.指针有空指针(NULL或nullptr)但是引用没有空引用
4.指针可以不在定义的时候初始化,但是引用必须在定义的时候初始化
5.指针可以有多级指针,引用只有一级,没有多级引用
6.指针作为形参的时候,使用需要判断其合法性,引用不需要(没有空引用)
7.对指针解引用(*)后进行操作会影响到变量本身,引用直接进行操作就会影响变量本身
8.sizeof求得指针的大小是4字节(x86系统),sizeof求的引用时变量原有类型的大小
从底层实现来看:
引用的实现其实时使用的指针,不过使用的不是普通的指针,而是自身为常性的指针:
int a = 10;
int& b = a;
int const * c = a;
这里的b和c在底层实现是一样的(并不代表在语法层面上相同,只是说在底层实现时相同的方法)