函数返回值有很多类型,但是什么时候该返回引用,而什么时候又该返回非引用呢?它们之间有什么区别吗?
让我们来看两个例子:
- //函数返回引用
- int &test1(int test_array[])
- {
- return test_array[1];
- }
- //函数返回普通类型
- int test2(int test_array[])
- {
- return test_array[1];
- }
仔细观察这两个函数,你会发现函数主体是一样的:return test_array[1];
那它们返回的结果是否一样呢?
- void main(int argc,char *argv[])
- {
- int test[5]={0,1,2,3,4};
- test1(test);
- test2(test);
- }
调试该程序:
分别在test1、test2内部下断点:
- int &test1(int test_array[])
- {
- 00411C40 push ebp
- 00411C41 mov ebp,esp
- 00411C43 sub esp,0C0h
- 00411C49 push ebx
- 00411C4A push esi
- 00411C4B push edi
- 00411C4C lea edi,[ebp-0C0h]
- 00411C52 mov ecx,30h
- 00411C57 mov eax,0CCCCCCCCh
- 00411C5C rep stos dword ptr es:[edi]
- return test_array[1];
- 00411C5E mov eax,dword ptr [test_array]
- //这里的mov eax,dword ptr [test_array]是不是有些迷惑呢?
- //实际上这里应该是mov eax,dword ptr [ebp+8],即[ebp+8]处存放第一个参数
- //的地址,所以这里的eax是获得的数组test_array的基址
- 00411C61 add eax,4
- //这里就应该十分明了:获得下标为1的数组的地址
- }
- int test2(int test_array[])
- {
- 00411D90 push ebp
- 00411D91 mov ebp,esp
- 00411D93 sub esp,0C0h
- 00411D99 push ebx
- 00411D9A push esi
- 00411D9B push edi
- 00411D9C lea edi,[ebp-0C0h]
- 00411DA2 mov ecx,30h
- 00411DA7 mov eax,0CCCCCCCCh
- 00411DAC rep stos dword ptr es:[edi]
- return test_array[1];
- 00411DAE mov eax,dword ptr [test_array]
- //这里就不需要再解释了吧
- 00411DB1 mov eax,dword ptr [eax+4]
- //直接获得下标为1的数组的值
- }
结论:“&”对函数返回值的类型有着本质上的影响,如果加“&”返回该类型的指针类型,如果不加则返回该类型的基本类型(即使在函数实体内的操作是完全一样的情况下),同时要注意返回值的作用范围,即如果引用一个在作用域在该函数内的变量就会引发错误,因为在该函数结束时,被引用变量的生命周期也会结束,所以将返回一个不存在的值。当函数要返回一个作用域在该函数范围的变量时不能使用“&”!