1

在 C++ 中,使用const对临时的引用是有效的:

const std::string& s = std::string("abc");
std::cout << s.length() << std::endl; // valid because string instance is still alive

但是,如果临时是通过另一种类型的转换创建的,这是否成立?

例如:

struct Foo
{ 
    ~Foo()
    {
        cout << "Foo destructor?" << endl;
    }
};

struct Bar
{ 
    operator Foo()
    {
        return Foo();
    }

    ~Bar()
    {
        cout << "Destructor" << endl;
    }
};

Foo getFoo()
{
    return Foo();
}

Bar getBar()
{
    return Bar();
}

int main()
{
    const Foo& f = getBar();
        /* is f valid here, or is it a dangling reference? */
    std::cout << "We're still in main!" << std::endl;
}

我注意到 Bar 的析构函数在输出之前 We're still in main被调用,这让我认为这Foo& f是一个悬空引用。我对么?

4

2 回答 2

2

临时的创建方式无关紧要。如果将 aconst X&或 an绑定X&&到本地纯右值,则临时的生命周期会延长到引用的生命周期。

于 2013-10-29T18:43:11.253 回答
2

该函数getBar创建一个类型的对象Bar并立即销毁返回它的副本

Bar getBar()
{
    return Bar();//the lifetime of Bar() is only on this line;
}

编辑:

对于源代码中的问题是否const Foo & f有效;是的,这是因为getBar返回一个对象副本。同样在检查代码后,我看到它首先返回 Bar 的副本,然后将其转换为Foo

我还必须提到 RVO(来自评论部分),它是编译器的优化。对象的生命周期仍然由它的作用域定义,{}但是在这种情况下,构造是在函数内部完成的,而破坏是在函数外部完成的。这种优化不会让你给变量命名,如下所示:

Bar getBar()
{
    Bar tmp_value;
    return tmp_value;
}

拉兹万。

于 2013-10-29T18:35:41.353 回答