C++ Reference
引用实际上是指针的一个扩展,但是又不同于指针。
首先,引用必须引用一个已经存在的变量。不像指针,指针可以被声明为空指针,但引用不可以。引用本身并不是一个新的变量,它并不实际占用内存空间,也并不实际储存数据,它仅仅是一个变量的引用。
举例说明:
#include <iostream>
#define LOG(x) std::cout << x << std::endl;
int main()
{
int a = 5;
int& ref = a;
std::cin.get();
}
在上述代码中,ref 是变量 a 的引用。实际上,ref 相当于变量 a 的别名。 如果将上述代码编译,实际上只会在内存空间中创建一个变量 a。
如果改变 ref 的值,打印 a:
#include <iostream>
#define LOG(x) std::cout << x << std::endl;
int main()
{
int a = 5;
int& ref = a;
ref = 2;
LOG(a);
std::cin.get();
}
则 a 的值也为 2.
即变量的引用仅仅相当于该变量的别名,并不会重新生成一个变量。
那么既然仅仅只是给变量起一个别名,什么情况下我们需要用到引用呢?就上述情况而言,我们直接调用变量 a 就可以了,为啥要多写几行代码来创建一个引用呢?
看下面的例子:
#include <iostream>
#define LOG(x) std::cout << x << std::endl;
void Increment(int value)
{
value++;
}
int main()
{
int a = 5;
Increment(a);
LOG(a);
std::cin.get();
}
如果我们想要变量 a 调用 Increment,然后自加 1. 上述代码是无法实现这个结果的 ,实际输出 a 的值仍然为 5。这是因为 将变量 a 传给方法 Increment, 相当于复制该变量到方法里。
等同于如下效果:
void Increment(int value)
{
int a = 5;
value++;
}
所以并不会改变变量 a 的值。
那想要达到我们想要的结果,如何做呢?
首先,当然,指针是可以做到的。指针指向的是变量的内存空间中的地址,即变量实际存在的地方。如果我们直接把变量的地址传给 Increment 函数,那肯定是可以改变该变量的值的,如下所示:
#include <iostream>
#define LOG(x) std::cout << x << std::endl;
void Increment(int* value)
{
(*value)++;
}
int main()
{
int a = 5;
Increment(&a);
LOG(a);
std::cin.get();
}
输出结果为 6.
可以看到,指针确实能得到我们想要的结果。但有没有更简单清晰一点的方法呢?
#include <iostream>
#define LOG(x) std::cout << x << std::endl;
void Increment(int& value)
{
value++;
}
int main()
{
int a = 5;
Increment(a);
LOG(a);
std::cin.get();
}
运行结果为 6. 可见引用也可以实现我们的目的,并且让代码看起来更加简洁。
再看一个例子:
#include <iostream>
#define LOG(x) std::cout << x << std::endl;
int main()
{
int a = 5;
int b = 8;
int& ref = a;
ref = b;
LOG(a);
LOG(b);
std::cin.get();
}
输出结果为 8, 8。 即变量 a 等于 b = 8。 为什么会这样? 因为引用只能被初始化一次,指向一个变量,并且不能够改变。同时,引用在被声明的同时一定要被初始化。当然,指针是可以先指向一个变量,然后指向另一个变量的。