C++引用探索
来源:互联网 发布:sap系统优缺点知乎 编辑:程序博客网 时间:2024/06/06 07:05
c++引用实质上就是指针(用的是VC6.0其它编译器可能不一样)。
一.作为函数的形参
#include <iostream>using namespace std;int fun(int &a,int &b,int &c){return a+b+c;}int main(void){int a=1;int b=2;int c=3;int e=fun(a,b,c);cout<<e<<endl;return 1;}
首先时定义了a,b,c三个变量的汇编如下:(ebp为栈底寄存器,esp为栈顶寄存器,eax为通用寄存器就像c++普通变量一样
int a=1; mov dword ptr [ebp-4],1 //将1存储在ebp-4的内存单元int b=2; mov dword ptr [ebp-8],2//将1存储在ebp-8的内存单元int c=3; mov dword ptr [ebp-0Ch],3//将1存储在ebp-12的内存单元
int e=fun(a,b,c);//看看c++一句话汇编要这么多呵呵lea eax,[ebp-0Ch]//取ebp-12内存单元的地址,将该地址值存放在eax里 3push eax //将eax的值也就是ebp-12的地址压栈lea ecx,[ebp-8]//同上2push ecx//同上lea edx,[ebp-4]//同上1push edx//同上call @ILT+380(fun) (00401181)最后调用fun函数
写到这里好像还是不知道要表达什么?不要着急从上面我们可以得到如下结论:
通过编译器编译得知fun三个参数是引用,会将实参的地址push到main函数栈的顶端(说是顶端其实也是相对的,这里的顶端是指push的方向。有的可能从高地址使用到地地址,有的可能是从地地址使用到高地址,其实这不是主要的)。这样使esp寄存器就保存了指向保存ebp-4单元的地址(也就是保存1的内存单元地址)的内存单元的地址。(其实也就是所谓的esp指向了内存单元m1 ,而m1就保存了,内存单元m2的地址)。
好了,我们先进入fun函数的内部进行查看。
以下是fun函数内部的重要准备工作的汇编
push ebp//首先将ebp的值保存压栈,这起到保护现场,等fun函数完了有句这样的pop edp这样是edp又恢复到进去fun函数之前的值了。(这就牵涉到函数中断等相关问题了这里不做表述) mov ebp,esp
sub esp,40h//移动esp栈顶指针,为局部变量和预留空间的内存单元做准备
return a+b+c; mov eax,dword ptr [ebp+8]//相当于eax=edp+8,此时eax也就等于main函数 实参 a的地址 mov eax,dword ptr [eax]//从通过地址得到eax的值,也就是1 mov ecx,dword ptr [ebp+0Ch]//同上 add eax,dword ptr [ecx]//将ecx保存的内存里面的值与eax相加,相当于eax=eax+*ecx mov edx,dword ptr [ebp+10h] add eax,dword ptr [edx]
从fun函数汇编看出,fun函数访问的形参引用的值是保存的main函数里面的,然后通过ebp栈底寄存器内存偏移,可以访问到a,b,c的值了。因为调用与被调用的函数是处在一段连续的内存块,通过逻辑栈将其分开。
二.局部变量的引用
int a=1;
int& b=a;
如以上语句,汇编如下。
int a=1;mov dword ptr [ebp-4],1//这就不解释了int& b=a; lea eax,[ebp-4]//值也是去ebp-4内存单元的地址,放到eax mov dword ptr [ebp-8],eax//将eax的值放在ebp-8内存单元里
cout<<b;
mov ecx,dword ptr [ebp-8]mov edx,dword ptr [ecx]//这也是首先访问ebp-8内存单元里面所存的地址,然后通过地址得到改地址里的值。
比较简单,但也有个特殊之处就是因为b在这里也是局部变量所以也放在了函数开辟好的预留空间里。通常预留空间的大小为40h+sizeof(class)*sum。class为类型,sum为函数局部变量的个数。
引用的使用就不完全列举了,下面列举下指针,随便与引用做个比较。
同样一段这样的代码我把它改成指针
int a=1;
int *b=&a;
汇编如下:
int a=1;
mov dword ptr [ebp-4],1
int *b=&a;
lea eax,[ebp-4]
mov dword ptr [ebp-8],eax
瞧瞧简直一模一样,至少在VC6.0是这样处理的。这可不是我故意这样做的,事实就是如此。
这就充分说明对引用实际上与指针没什么不同,但C++为什么还要把扩展引用这个功能呢?
我想既然它叫c++那么c里面有的它必须有,c里面没有的它也要有不然怎么++呢?
不存在空的引用,引用必须初始化。等等这些都可以在编译期帮我们把危险降低。而指针就没有这个限制,有时一个空的指针,或者没有初始化而使用的指针都是造成软件崩溃的原因,所以使用指针你必须很小心。还是应该多使用引用啊。
但不要使用这样的引用
int a;
int &b=a;
或者
int &b=fun();
这样会使引用到一些不确定的内存里面去。
- C++中extern “C”含义深层探索[引用]
- C++引用探索
- com 引用计数探索
- C和C++函数的相互引用----C++中extern “C”含义深层探索[转载]
- C和C++函数的相互引用----C++中extern “C”含义深层探索[转载]
- C文件操作探索
- C#:多线程编程探索
- C/C++深层探索
- CUDA C编程探索
- 探索extern "C"
- 引用(c++)
- C++----引用
- c++-引用
- C ++ 引用
- 【c++】引用
- 【c++】引用
- C++:引用
- C++:引用
- Parse,不用配置的后台服务器
- 3ds max中mat文件
- Android平台实现https信任所有证书的方法
- 常用hadoop命令
- Struts2---->环境搭建及HelloWorld
- C++引用探索
- 雷锋微视点:腾讯电商、搜搜、微信将出门独立
- SAP LUW 逻辑工作单元
- eclipse 注释
- Android permission 权限类及中文说明
- 三、装饰模式
- Struts2 OGNL表达式详解
- 批处理文件打包.bat
- java 定时器