你必须非常努力,才能看起来毫不费力!
分类:
2008-10-06 12:48:53
我们先从比较熟悉的指针反汇编来分析,之后对比引用反汇编,看看他们的区别极其联系
8: int ival=1024;
0040F5F8 mov dword ptr [ebp-4],400h
9: int &refVal=ival;
0040F5FF lea eax,[ebp-4]
0040F602 mov dword ptr [ebp-8],eax
10:
11: cout<
0040F605 push 2Ch
0040F607 mov ecx,dword ptr [ebp-8]
0040F60A mov edx,dword ptr [ecx]
0040F60C push edx
0040F60D mov ecx,offset cout (00428ac0)
0040F612 call ostream::operator<< (00401280)
0040F617 mov ecx,eax
0040F619 call @ILT+15(ostream::operator<<) (00401014)
12: cout<<&refVal<<',';
0040F61E push 2Ch
0040F620 mov eax,dword ptr [ebp-8]
0040F623 push eax
0040F624 mov ecx,offset cout (00428ac0)
0040F629 call ostream::operator<< (004011e0)
0040F62E mov ecx,eax
0040F630 call @ILT+15(ostream::operator<<) (00401014)
13:
14: int ival2=2048;
0040F635 mov dword ptr [ebp-0Ch],800h//将800h赋给[ebp-0Ch]这个地址对应的存储单元
15: int *pointer=&ival2;
0040F63C lea ecx,[ebp-0Ch] //将[ebp-0Ch]这个地址传给寄存器ecx
0040F63F mov dword ptr [ebp-10h],ecx//将ecx的值传给[ebp-10h]对应的存储单元(即:pointer)
16:
17: cout<<*pointer<<',';
0040F642 push 2Ch
0040F644 mov edx,dword ptr [ebp-10h] //将pointer存储的地址值传给edx
0040F647 mov eax,dword ptr [edx] //将edx存储地址对应的值传给eax(即:*pointer)
0040F649 push eax//将*pointer值入栈
0040F64A mov ecx,offset cout (00428ac0)
0040F64F call ostream::operator<< (00401280)
0040F654 mov ecx,eax
0040F656 call @ILT+15(ostream::operator<<) (00401014)
18: cout<
0040F65B push 2Ch
0040F65D mov ecx,dword ptr [ebp-10h] //将pointer存储的地址值传给ecx
0040F660 push ecx//将pointer值入栈
0040F661 mov ecx,offset cout (00428ac0)
0040F666 call ostream::operator<< (004011e0)
0040F66B mov ecx,eax
0040F66D call @ILT+15(ostream::operator<<) (00401014)
运行结果:2048,0X0013FF74,1024,0X0013FF7C
之前,先说明下操作符”*”;C++预定义了一个饿专门的取地址(address-of)操作符(&).当我们把他应用在一个对象上时,返回的是对象的地址值.因此,为了将ival2地址值赋给pointer,我们这样写:
int *pointer;
pointer=&ival;
为了访问pointer所指向的实际对象,我们必须先用解引用(dereference)操作符(*)来解除pointer的引用(dereference pointer).我们暂且这样来认为这段程序:变量pointer引用(存放)了一个对象ival的地址,我们通过一把钥匙”*”来开启pointer地址对应房间的大门,从而进入这个房间.回到程序中,也就是说只要”解引用+地址”就能访问到对应内存单元.我们暂且认为”解引用+地址=指针”吧.因此,我个人认为指针这个概念因该是广义的.比如下面代码:
int ival3=3096;
int &refVal=ival3;
cout<
这是所谓的关于引用类型的使用,&refVal是存放的ival3的地址.通用我们可以通过cout<<*(&refVal)<
从目前的代码来看,无论是指针pointer还是引用refVal,他们都是存放的所指对象的地址值.那么,他们是否就是一样的呢?引用和指针的区别在哪里?
我们知道,对于指针*pointer, 我们可以通过一个取地址操作符”&”将一个对象的地址赋给pointer,这样就可以改变指针所指的对象了.那么自然的引用是否也可以呢?
首先,我们可以通过&refVal来得到被引用对象ival的地址(int &refVal=ival,这就类似于通过pointer=&ival2得到对象的地址值一样).其次,问题的关键就在于我们是否可以像指针那样随意的修改引用本身(即:像修改pointer中的地址那样修改&relVal中的地址值).不幸的是,我们无法通过任何C++语法像指针那样方便的修改被引用对象的地址值.
因此,引用一旦被定义(必须先初始化),就再也无法随意更改指向其他对象,他们是绑定在一起了.