关于引用延长临时对象生命期的问题

colorfulcode 2014-01-16 09:34:56

class A
{
public:
~A(){ cout << "end A" << endl; };

A& Show(){ cout << "show" << endl;return *this; }
};

A fun()
{
return A();
}

A &a = fun().Show(); // 这里



如上,我本以为执行完“fun().Show()”后,a依旧能引用到函数fun调用后返回的临时对象,可是结果却发现,“fun().Show()”调用之后那个临时对象就析构了。

百思不得其解,莫非是调用fun函数后,其返回的临时对象并没有立即的被a引用,而是用这个临时对象调用Show函数,进而导致a没能“第一时间”引用上临时对象,结果导致调用完show函数后析构了?
...全文
350 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
colorfulcode 2014-01-17
  • 打赏
  • 举报
回复
10L: 你说的这个我知道。 我在2L中说的那个“不理解”,主要指的是为什么在解释临时变量最终何时析构时,不仅说“被引用绑定的临时变量在引用生命期结束后析构”,又说一句“或者临时变量生命期结束,视哪个先抵达”。 既然引用已经绑定了临时变量,那自然的它俩应该就是一样的生命期了,既然都是同样的生命期了,书上又为何这样说呢。 什么情况下会有临时变量会先于绑定它的引用结束生命呢
colorfulcode 2014-01-17
  • 打赏
  • 举报
回复
8L: 后来想了想,应该就是你说的这个原因。 加上我自己的理解,Show函数间接的返回了临时对象的引用,使得a没能直接引用上这个临时对象,从而没能延长临时对象。
colorfulcode 2014-01-17
  • 打赏
  • 举报
回复
目前手边没有这书,具体多少页不记得。 不过书上的那句话是被方框框起来的
colorfulcode 2014-01-17
  • 打赏
  • 举报
回复
引用 13 楼 supermegaboy 的回复:
[quote=引用 12 楼 ColorfulCode 的回复:] 10L: 你说的这个我知道。 我在2L中说的那个“不理解”,主要指的是为什么在解释临时变量最终何时析构时,不仅说“被引用绑定的临时变量在引用生命期结束后析构”,又说一句“或者临时变量生命期结束,视哪个先抵达”。 既然引用已经绑定了临时变量,那自然的它俩应该就是一样的生命期了,既然都是同样的生命期了,书上又为何这样说呢。 什么情况下会有临时变量会先于绑定它的引用结束生命呢
红色那句话的确让人感到迷惑,请问你从什么书上看到这段话?这段话的上下文是什么?[/quote] 《深入探索c++对象模型》中关于“临时对象”的一节,从目录中也可找到
飞天御剑流 2014-01-17
  • 打赏
  • 举报
回复
引用 12 楼 ColorfulCode 的回复:
10L: 你说的这个我知道。 我在2L中说的那个“不理解”,主要指的是为什么在解释临时变量最终何时析构时,不仅说“被引用绑定的临时变量在引用生命期结束后析构”,又说一句“或者临时变量生命期结束,视哪个先抵达”。 既然引用已经绑定了临时变量,那自然的它俩应该就是一样的生命期了,既然都是同样的生命期了,书上又为何这样说呢。 什么情况下会有临时变量会先于绑定它的引用结束生命呢
红色那句话的确让人感到迷惑,请问你从什么书上看到这段话?这段话的上下文是什么?
unituniverse2 2014-01-17
  • 打赏
  • 举报
回复
临时对象生命期的延长仅限于被延长的对象是值的情况。
unituniverse2 2014-01-17
  • 打赏
  • 举报
回复
lz代码是设计错误。 函数返回引用,函数体作用域阻断了右值生命期延长的可能。 而原本右值需要用常左值引用或者右值引用接受,结果代码里却是利用指针取内容为左值的特性先变右值为左值再返回。 总之不可以返回非静态局部变量的引用,不管是临时变量还是非临时变量。 能编译通过的代码不一定就是正确的。
飞天御剑流 2014-01-17
  • 打赏
  • 举报
回复
我看了下原文,是这样说的: So the rule is that a temporary bound to a reference persists for the lifetime of the reference initialized or until the end of the scope in which the temporary is created, whichever comes first. 后半句话所对应的场景应该如下:

const A& fun()
{
    return A();
}
const A &a = fun();
飞天御剑流 2014-01-16
  • 打赏
  • 举报
回复
引用 2 楼 ColorfulCode 的回复:
以前书上有一句话我一直不理解: “如果一个临时对象被绑定到一个reference,对象将被延长,直到这个reference生命结束,或者到临时对象的生命结束,视哪个情况先到” 难道我上面的问题和这句红色有关
这句话指的是const A& a = fun();这种情况,这时候fun()返回的临时对象的生命期被延长到至少与a一样长。 你可以如下这样试验一下结果: const A& a = fun(); std::cout << "test"; return 0; 你会看到endA会出现在test之后,而不是之前,即fun()被延长了。
  • 打赏
  • 举报
回复
The language says "temporaries die at the end of the statement, unless they are bound to const reference, in which case they die when the reference goes out of scope". Applying that rule, it seems a is already dead at the beginning of the next statement, since it's not bound to const reference (the compiler doesn't know what fun() returns). This is just a guess however.
vipcxj 2014-01-16
  • 打赏
  • 举报
回复
函数返回引用,不是临时对象。

fun()
返回的确实是个A的临时对象。

Show()
返回的是个引用,不是临时对象,所以不能延长它返回东西的生命周期,但关键问题是它引用的是fun()返回的一个临时对象,于是语句结束,fun()返回的临时对象就被回收了~
iamnobody 2014-01-16
  • 打赏
  • 举报
回复
临时对象被延长生命周期是有条件的,显然你写的代码不满足这个条件. 详见
colorfulcode 2014-01-16
  • 打赏
  • 举报
回复
show 返回的是 *this的引用啊
  • 打赏
  • 举报
回复
引用 3 楼 akirya 的回复:
是 const 引用
const A &a = fun().Show();
呃这个错误 show返回的不是临时变量.所以const &也无法延长生存周期.
#include <iostream>
using namespace std;
class A
{
public:
    ~A(){ cout << "end A" << endl; };
 
	void Show()const{ cout << "show" << endl; }
};
 


A fun()
{
    return A();
}
 
int main()
{
	const A &a = fun();
	a.Show(); // 
	puts("a");
}
colorfulcode 2014-01-16
  • 打赏
  • 举报
回复
引用 3 楼 akirya 的回复:
是 const 引用
const A &a = fun().Show();
试过了,没用。 VC GCC一样
  • 打赏
  • 举报
回复
是 const 引用
const A &a = fun().Show();
colorfulcode 2014-01-16
  • 打赏
  • 举报
回复
以前书上有一句话我一直不理解: “如果一个临时对象被绑定到一个reference,对象将被延长,直到这个reference生命结束,或者到临时对象的生命结束,视哪个情况先到” 难道我上面的问题和这句红色有关
colorfulcode 2014-01-16
  • 打赏
  • 举报
回复
难道“fun().Show()”不是一个完整表达式?

64,648

社区成员

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

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