struct A { A(int) : i(new int(783)) { std::cout << "a ctor" << std::endl; } A(const A& other) : i(new int(*(other.i))) { std::cout << "a copy ctor" << std::endl; } ~A() { std::cout << "a dtor" << std::endl; delete i; } void get() { std::cout << *i << std::endl; } private: int* i; }; const A& foo() { return A(32); } const A& foo_2() { return 6; } int main() { A a = foo(); a.get(); }
我知道,返回对本地值的引用是不好的.但是,另一方面,const引用应该延长临时对象的生命周期.
为什么?我的意思是有人可以解释一下子发生什么事吗?
我的推理链在哪里出错?
FOO():
> A(32) – ctor
> return A(32) – 创建一个对本地对象的const引用并返回
> A a = foo(); – a由foo()返回值初始化,返回值超出范围(表达式外)并被销毁,但a已经初始化;
FOO_2():
> return 6 – 隐式创建A类型的临时对象,创建对该对象的const引用(延长其生命周期)并返回
> A a = foo(); – a由foo()返回值初始化,但a已经初始化;
解决方法
在语言规范中明确规定了每个特定上下文的临时生命周期扩展规则.而且它说
12.2 Temporary objects
5 The second context is when a reference is bound to a temporary. […] A temporary bound to the returned value in a function return statement
(6.6.3) persists until the function exits. […]
您的临时对象在函数退出时被销毁.这发生在收件人对象的初始化开始之前.
你似乎认为你的临时生活应该比这更长寿.显然,您正在尝试应用规则,该规则表明临时应该存在直到完整表达式结束.但该规则不适用于在函数内部创建的临时数.这种临时工的生命周期由他们自己的专门规则决定.
如果有人试图使用返回的引用,则foo和foo_2都会产生未定义的行为.