临时终身延长

时间:2013-06-28 10:31:19

标签: c++ reference lifetime object-reference temporary-objects

标准的12.2.5部分说:

  

临时绑定到函数调用中的引用参数(5.2.2)   一直持续到包含完整表达式的完成   呼叫。临时绑定到函数返回的返回值   语句(6.6.3)一直存在,直到函数退出。在所有这些   案例,评估表达期间创建的临时表   初始化引用,除了临时的   引用是绑定的,在完整表达式结束时被销毁   它们是按照完成的顺序创建的   他们的建设。

我试着理解的代码是:

#include <iostream>

const int& foo(const int& fooRef)
{
    return fooRef;
}                                        // #0

int main (void)
{
    const int& numberRef = foo(5);     // #1
    std::cout << numberRef;            // #2
    return 0;
}

在线#1上创建一个临时对象并绑定到fooRef的{​​{1}}参数。 foofooRef行被销毁。所以我认为临时应该在这里销毁,因为生命延长不是传递性的。

问题:

  1. #0是什么意思?这是until the function exits吗?

  2. 为什么我会得到untill it finished executing输出。第5行还有临时对象吗?

  3. 如何解释标准引用以弄清楚此示例的工作原理?

  4. 非常感谢参考标准的逐步原子演练。谢谢!

    P上。 S.一个接受的答案here也告诉代码是#2我不明白,为什么我得到这样的程序输出。

2 个答案:

答案 0 :(得分:3)

  

直到函数退出是什么意思?这是否意味着直到它完成执行?

  

为什么我得到5输出。第2行上是否还存在临时对象?

取消引用未绑定到活动对象的引用是未定义的行为,因此您可以获得5以及42以及其他任何内容(包括崩溃)。对于具有未定义行为的程序,您根本无法期待。

  

如何解释标准引用以弄清楚此示例的工作原理?

非常像你已经做过的那样。临时绑定到函数参数fooRef,它从函数返回时被销毁。由于该临时值与返回值绑定,因此该函数返回时该对象不再存在。稍后,您将取消引用悬空引用,它会为您提供UB。

答案 1 :(得分:1)

  1. 这意味着直到结束括号,即}

  2. 你调用了UB,你有一个悬空引用。

  3. 尝试对代码进行以下修改并查看其打印内容。它可能会打印6因为这是堆栈中的最后一个。或者尝试传递一个std::string,你可能会崩溃。

    int main (void)
    {
        const int& numberRef = foo(5);  
        foo(6);
        std::cout << numberRef;
        return 0;
    }