首先什么是引用?
引用不是新定义的一个变量,而是给已经存在的变量取了一个别名,编译器不回为引用开辟一个新空间,引用与实体共用同一块内存。
举个例子:
void Swap(int& x)
{
x = 2;
cout << "x:" << &x << endl;
}
int main()
{
int a = 1;
cout << "a = " << a << endl;
cout << "a:" << &a << endl;
Swap(a);
cout << "a = " << a << endl;
system("pause");
return 0;
}
我们可以看到,被调用函数的形参 x 是实体 a 的引用,我们现在在函数内部修改了x 的值,并把他们的地址打印出来,我们知道:如果函数形参是一个临时变量的话,那么函数内部修改 x 的值,就不会对主函数里的实体 a 造成任何影响,那我们就来看看运行结果是什么?
哇哦~,我们看到了函数内部修改 x 的值,改变了实体 a的值,那么引用x 就不是一个临时变量,那么他究竟是何方神圣?我们清晰的发现实体a的值改变了,而且 引用x 和 实体a 的地址也是一样的,原来:形参引用 x 就是和实体 a 共用一块内存,引用是实体的一个别名。
那么问题来了,引用到底是如何实现的呢?让我们去看看它在底层做了哪些事情吧~
我们来举个简单的例子看看:
我们再来看看利用指针做同样的事情~
我们调试指针看一下:
我们调试引用看一下:
我们惊奇的发现,指针和引用在底层做着同样的事情,终于真相大白了,引用在底层做着和指针同样的工作,引用和指针都是通过编译器来控制并实现的~
现在就应该引出了我们的主题了:指针和引用有何区别?
相同点:
底层处理方式一模一样、在底层引用变量实际上是有空间的【在底层引用是按照指针的方式来进行处理】。
不同点:
1 引用定义时必须要初始化,而指针定义时可以直接置空。
2 引用与实体共用同一块内存,而指针变量单独有一个空间。
3 引用大小就是实体的大小,而指针的大小【32位平台下占4个字节】。
4 没有NULL引用,但是有NULL指针
5 引用自增1就是给实体自增1, 指针自增1,意思是跳过一个指针变量大小。
6 引用比指针更安全,引用不需要判空,而指针需要判空。
7 访问实体的方式不同,指针需要由用户显式解引用,引用由编译器处理。
8 有多级指针,但是没有多级引用。
9 一个引用一旦引用了一个实体,在这个工程里就不能在引用其他实体;而一个指针可以随时指向任何一个实体。