引用的理解

来源:互联网 发布:socket函数 linux 编辑:程序博客网 时间:2024/05/17 09:17

转自:http://blog.csdn.net/wanwenweifly4/article/details/6739687

引用类型到底是什么?它和指针有什么关系?它本身占用内存空间吗? 带着这些疑问,我们来进行分析。 先看代码:

#include <stdio.h>#include <iostream>using namespace std;void main(){   int x = 1;   int &b = x; } 

通过汇编查看代码如下:

9:       int x = 1;00401048   mov         dword ptr [ebp-4],110:      int &b = x;0040104F   lea         eax,[ebp-4]00401052   mov         dword ptr [ebp-8],eax

可以知道x的地址为ebp-4,b的地址为ebp-8,因为栈内的变量内存是从高往低进行分配的。所以b的地址比x的低。
lea eax,[ebp-4] 这条语句将x的地址ebp-4放入eax寄存器

mov dword ptr [ebp-8],eax 这条语句将eax的值放入b的地址ebp-8中

上面两条汇编的作用即:将x的地址存入变量b中,这不和将某个变量的地址存入指针变量是一样的吗?

所以从汇编层次来看,的确引用是通过指针来实现的。

下面我们通过程序来验证,我们知道,在程序一层我们只要直接涉及到引用变量的操作,我们操作的总是被引用变量,即编译器帮我们做了些手脚,总是在引用前面加上*。所以我们要读取真正的“引用变量的值”,必须采取一定的策略,好吧,我们就按照变量在栈中分布的特点来绕过编译器的这个特点。

#include <stdio.h>#include <iostream>using namespace std;void main(){   int x = 1;   int y = 2;   int &b = x;   printf("&x=%x,&y=%x,&b=%x,b=%x\n",&x,&y,&y-1,*(&y-1)); } 
输出结果为:&x=12ff7c,&y=12ff78,&b=12ff74,b=12ff7c
Press any key to continue
void main(){   int x = 1;   int &b = x;   printf("&x=%x,&b=%x\n",&x,&b); } 
输出结果为::&x=12ff7c,&b=12ff7c.

b的地址我们没法通过&b获得,因为编译器会将&b解释为:&(*b) =&x ,所以&b将得到&x。也验证了对所有的b的操作,和对x的操作等同。

但是我们可以间接通过&y-1来得到b的地址,从而得到b的值:*(&y-1) 从结果可以知道,b的值即x的地址,从而可以知道,从地层实现来看,引用变量的确存放的是被引用对象的地址,只不过,对于高级程序员来说是透明的,编译器屏蔽了引用和指针的差别。

下面是程序的变量在内存栈中的分布,引用变量一样也占用内存空间,而且应该是4个字节的空间。

虽然从底层来说,引用的实质是指针,但是从高层语言级别来看,我们不能说引用就是指针,他们是两个完全不同的概念。有人说引用是受限的指针,这种说法我不赞同,因为从语言级别上,指针和引用没有关系,引用就是另一个变量的别名。对引用的任何操作等价于对被引用变量的操作。从语言级别上,我们就不要去考虑它的底层实现机制啦,因为这些对你是透明的。所以在面试的时候,如果面试的人问到这个问题,可以先从语言级别上谈谈引用,深入的话就从底层的实现机制进行分析。而不能什么条件没有就说:引用就是指针,没有差别,......之类的回答



以下内容摘自网上,觉得挺好的,借用过来

什么是引用?

对象的别名(另一个名称)。

引用经常用于“按引用传递(pass-by-reference)”:
 void swap(int& i, int& j) {   int tmp = i;   i = j;   j = tmp; }  int main() {   int x, y;   // ...   swap(x,y); }
此处的 i 和 j 分别是main中的 x 和 y。换句话说,i 就是x —— 并非指向 x 的指针,也不是x 的拷贝,而是 x 本身。对 i 的任何改变同样会影响x,反之亦然。

OK,这就是作为一个程序员所认知的引用。现在,给你一个不同的角度,这可能会让你更糊涂,那就是引用是如何实现的。典型的情况下,对象 x 的引用i 是x 的机器地址。但是,当程序员写 i++ 时,编译器产生增加 x 的代码。更详细的来说,编译器用来寻找x 的地址位并没有被改变。C 程序员将此认为好像是 C 风格的按指针传递,只是句法不同 (1) 将 & 从调用者移到了被调用者处,(2)消除了*s。换句话说,C 程序员会将i 看作为宏(*p),而 p 就是指向 x 的指针(例如,编译器自动地将潜在的指针解除引用;i++被改变为(*p)++;i = 7 被自动地转变成*p = 7)。

很重要:请不要将引用看作为指向一个对象的奇异指针,即使引用经常是用汇编语言下的地址来实现的。引用就是对象。不是指向对象的指针,也不是对象的拷贝,就是对象。

 

 以下内容摘自网上,觉得挺好的,借用过来

0 0
原创粉丝点击