返回引用

delphiwcdj 2010-03-23 04:38:42
为什么下面可以输出:

#include <cstdio>
#include <vector>
using namespace std;

int& Fun();

int main()
{
int a=Fun();
printf("%d",a);
printf("\n");

return 0;
}

int& Fun()
{
int a=2;

return a;
}


这样不行:

#include <cstdio>
#include <vector>
using namespace std;

vector<char>& Fun();

int main()
{
vector<char> cvec;
cvec=Fun();
//cvec.swap(Fun());

for (vector<char>::iterator iter=cvec.begin();iter!=cvec.end();++iter)
{
printf("%d\t",*iter);
}
printf("\n");

return 0;
}

vector<char>& Fun()
{
// used var
vector<char> cvec(5,1);

return cvec;
}

谢谢!
...全文
230 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
asyuae 2012-06-08
  • 打赏
  • 举报
回复
那不是可以提高效率么????????????????????????????????????????????????????????
在寄存器中有地址,执行完F()后也没改变地址对应的值啊
柯本 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 mzlogin 的回复:]
GCC下对第一个程序也没报错,
是警告:
warning: reference to local variable 'a' returne
[/Quote]
这个是与编译器有关的,在C++ builder 中,根本不能编译的
Error E2363 t.cpp 20: Attempting to return a reference to local variable 'a' in
function Fun()
mzlogin 2010-03-23
  • 打赏
  • 举报
回复
GCC下对第一个程序也没报错,
是警告:
warning: reference to local variable 'a' returne
Julykey 2010-03-23
  • 打赏
  • 举报
回复
因为你返回的是对临时对象的引用,函数退出后,临时对象所在的内存就可能会被重新利用,得到的就不是你想要的了
gaohaibox 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 delphiwcdj 的回复:]
引用 13 楼 xiaoboalex 的回复:
引用 10 楼 delphiwcdj 的回复:
我的理解是返回type&; 编译器不会再声明一个临时变量,可以提高效率。
int a=Fun();// 此过程只是将Fun的返回值进行一次拷贝,没有用到函数中的局部变量

返回一个对象:系统要生成一个对象的拷贝返回;
返回一个引用:系统直接返回当前对象;

int a=Fun()……
[/Quote]

当函数返回一个对象的时候,创建一个临时对象存放到返回对象的内存中,但是该临时对象仅在调用它的外部表达式范围内有效。
gaohaibox 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 taodm 的回复:]
因为,出来混,迟早要还的。
你不能依赖于那些依赖于你的人品的代码。
[/Quote]

貌似很傻很天真你!
delphiwcdj 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 xiaoboalex 的回复:]
引用 10 楼 delphiwcdj 的回复:
我的理解是返回type&; 编译器不会再声明一个临时变量,可以提高效率。
int a=Fun();// 此过程只是将Fun的返回值进行一次拷贝,没有用到函数中的局部变量

返回一个对象:系统要生成一个对象的拷贝返回;
返回一个引用:系统直接返回当前对象;

int a=Fun();的确是拷贝Fun的返回值,但Fun返回的是引用,该引用指向Fun函数中定义的局部变量;a在获取值的时候并不是读取一个临时变量,而是直接从Fun里面定义的局部变量的内存中获取。
[/Quote]
我看了一下对应的汇编代码,你说的是对的。
当函数原型为int Fun()时,会将返回值mov到寄存器eax中保存,退出Fun后再mov到a中。
当函数原型为int& Fun()时,会将返回值的地址保存在eax中,退出Fun后再通过此地址读取数据到a中。

以前在书上好像读到过,当返回一个对象的时候,如果返回的不是引用,会自动调用构造函数再创建一个临时的对象。我在这里可能存在误解,本以为返回引用可以提高效率。现在得出结论:不要返回局部变量的引用。

等会儿结贴,谢谢大家!
testing2007 2010-03-23
  • 打赏
  • 举报
回复
返回局部对象的引用这种方式肯定是错误的,之所以你那里可以看到貌似正确的结果,这是编译器造成的,
ithiker 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 delphiwcdj 的回复:]
我的理解是返回type&,编译器不会再声明一个临时变量,可以提高效率。

C/C++ code

int a=Fun();// 此过程只是将Fun的返回值进行一次拷贝,没有用到函数中的局部变量


返回一个对象:系统要生成一个对象的拷贝返回;
返回一个引用:系统直接返回当前对象;
[/Quote]
恩,可以这么认为;这也不违背变量的作用域规则:局部变量在运行后都要销毁;

另外,我认为返回一个引用:系统只是返回的当前对象的一个“地址”(我们希望该对象还在生命周期内),就像传递一个对象,引用形参并不会复制该对象一样

如下,将引用去掉后,运行成功,说明确实有拷贝生成,要不然就违背了变量的作用域规则

#include <cstdio>
#include <vector>
using namespace std;

vector<char> Fun();

int main()
{
vector<char> cvec;
cvec=Fun();
//cvec.swap(Fun());

for (vector<char>::iterator iter=cvec.begin();iter!=cvec.end();++iter)
{
printf("%d\t",*iter);
}
printf("\n");

return 0;
}

vector<char> Fun()
{
// used var
vector<char> cvec(5,1);

return cvec;
}

断问天 2010-03-23
  • 打赏
  • 举报
回复
返回对象时默认调用拷贝构造函数,引用则为空
xiaoboalex 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 delphiwcdj 的回复:]

我的理解是返回type&,编译器不会再声明一个临时变量,可以提高效率。
C/C++ code

int a=Fun();// 此过程只是将Fun的返回值进行一次拷贝,没有用到函数中的局部变量


返回一个对象:系统要生成一个对象的拷贝返回;
返回一个引用:系统直接返回当前对象;
[/Quote]
int a=Fun();的确是拷贝Fun的返回值,但Fun返回的是引用,该引用指向Fun函数中定义的局部变量;a在获取值的时候并不是读取一个临时变量,而是直接从Fun里面定义的局部变量的内存中获取。
xiaoboalex 2010-03-23
  • 打赏
  • 举报
回复
#include <cstdio>
#include <vector>
using namespace std;


int* Fun()
{
int a=2;

return &a;
}

int main()
{
int *a=Fun();
printf("%d",*a);
printf("\n");
return 0;
}

上面的代码在VS2005上都可以通过(输出2),说明MS的编译器在函数返回以后并不会覆盖简单类型的局部变量的内存。
delphiwcdj 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zhoutanliang 的回复:]
容器对象只能用输入输出流输出
[/Quote]
有这么一说吗?
delphiwcdj 2010-03-23
  • 打赏
  • 举报
回复
我的理解是返回type&,编译器不会再声明一个临时变量,可以提高效率。

int a=Fun();// 此过程只是将Fun的返回值进行一次拷贝,没有用到函数中的局部变量

返回一个对象:系统要生成一个对象的拷贝返回;
返回一个引用:系统直接返回当前对象;
xiaoboalex 2010-03-23
  • 打赏
  • 举报
回复
有可能已经回收了内存,但是并没有修改里面的值;而对于vector,则直接回收并覆盖里面的内容。
xiaoboalex 2010-03-23
  • 打赏
  • 举报
回复
两段代码都是错误的,因为都返回了对局部变量的引用。
但是第一段代码在VS2005上运行正常,只能说是MS的编译器的奇迹:它对简单类型的局部变量的处理与对类类型的局部变量的处理不同,函数返回以后并没有销毁简单类型的内部变量。
昵称很不好取 2010-03-23
  • 打赏
  • 举报
回复
要想返回就弄成全局的吧,static之类的
柯本 2010-03-23
  • 打赏
  • 举报
回复
函数返回local变量,很多书上都有介绍,有些编译器直接会报错的.
你的程序一能运行,纯属偶然.因为结果是不可预见的
cy330206 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 taodm 的回复:]
因为,出来混,迟早要还的。
你不能依赖于那些依赖于你的人品的代码。
[/Quote]


。。。。
zyqde_0802 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 taodm 的回复:]

因为,出来混,迟早要还的。
你不能依赖于那些依赖于你的人品的代码。
[/Quote]

返回了局部变量,已经不存在了,有可能被覆盖了
加载更多回复(3)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧