![ce45832daaf91531bc476e68700c855a.png](https://img-blog.csdnimg.cn/img_convert/ce45832daaf91531bc476e68700c855a.png)
开始讲引用。一定要先看指针再看引用,因为本质上它们就是一回事,而引用不过是指针的syntax suger(这比喻),让指针更好用一点而已。引用是对指针的扩展,所以一定要理解指针是怎么用的,原理是什么,才能更好地理解引用。
虽说如此,在语法上,引用和指针还是有区别。我们可以创建一个指针变量,将它赋值为NULL,之后再改变它的值。但是引用不行。引用必须指向一个现有的变量,并且引用自己本身并不是新的变量,它们不占有内存,只是对变量的引用。
#include <iostream>
#include "log.h"
int main() {
int a = 5;
int& ref = a;
std::cin.get();
}
上面的代码中,紧跟在数据类型int之后的&就指明ref是一个引用,同时给ref赋值。这里注意区分,如果&用在变量前面,譬如 int*b = &a;那么此时&是用来取地址的;但是这里int&是说明引用。
如果不给ref赋值,那么语法出错。
![a9e94be432492f3f2606f8a9e46bb8fa.png](https://img-blog.csdnimg.cn/img_convert/a9e94be432492f3f2606f8a9e46bb8fa.png)
这里的ref相当于是变量a的假名。强调一下,并没有两个变量a和ref,只有一个变量a,以及对变量a的引用ref。
#include <iostream>
#include "log.h"
int main() {
int a = 5;
int& ref = a;
ref = 2;
log(a);
std::cin.get();
}
此时的结果a的值就成了2。
看下面这段代码:
#include <iostream>
#include "log.h"
void Increment(int value) {
value++;
}
int main() {
int a = 5;
int& ref = a;
Increment(a);
Log(a);
std::cin.get();
}
这个代码,大家应该都知道问题之所在,Increment此时是形参,所以不会对main()中的变量a产生任何影响。所以,一般来说可以使用指针或者引用来解决这个问题。形参相当于是传递了一个值过去,在子函数中相当于有一个局部变量,操作在这个局部变量上进行;而使用指针,是直接对这个指针所指向的内存位置进行操作,所以会影响main()中的变量。
使用指针的版本:
#include <iostream>
#include "log.h"
void Increment(int* value) {
(*value)++;
}
int main() {
int a = 5;
int& ref = a;
Increment(&a);
Log(a);
std::cin.get();
}
这里需要注意的是,(*value)++,++的优先级貌似比*要高,所以必须加()。
如果使用引用,代码会更简洁:
#include <iostream>
#include "log.h"
void Increment(int& value) {
value++;
}
int main() {
int a = 5;
int& ref = a;
Increment(a);
Log(a);
std::cin.get();
}
从上面的例子中可以看出,引用就是对指针的一点小改进,用起来更方便。所以,所以对指针不能进行的操作肯定也不能对引用进行。另外,ref不能进行修改。一旦绑定了ref,之后不能修改。这也是和指针不同的地方。
include <iostream>
#include "log.h"
void Increment(int& value) {
value++;
}
int main() {
int a = 5;
int b = 8;
int& ref = a;
ref = b;
Log(a);
ref = 9;
Log(a);
Log(b);
std::cin.get();
}
运行结果:
![894ccdd33590788db41940c6c38b3f4b.png](https://img-blog.csdnimg.cn/img_convert/894ccdd33590788db41940c6c38b3f4b.png)
上面代码的含义,ref = b;这一句不是将ref重新指向了b,而是将b的值8赋给了a。因此,后面的ref = 9;也只对a有影响,而不会对b有影响。