10

即使这个话题在这里讨论了很多次,我也找不到关于我的具体案例的结论性解释。会const延长RefTest临时的寿命吗?下面的例子合法吗?

#include <iostream>

class RefTest
{
public:
    RefTest(const std::string &input) : str(input) {}
    ~RefTest () {std::cout << "RefTest" << std::endl;}
private:
    std::string str;
};

class Child
{
public:
    Child (const RefTest &ref) : ref_m(ref) {}
    ~Child () {std::cout << "Test" << std::endl;}
private:
    const RefTest &ref_m;
};

class Test
{
public:
    Test () : child(RefTest("child")) {}//Will the temporary get destroyed here?
    ~Test () {std::cout << "Test" << std::endl;}
private:
    const Child child;
};

int main ()
{
   Test test;
}
4

2 回答 2

10

引用不会延长生命周期。该代码是合法的,但这只是因为您ref_m在构造函数完成后永远不会访问。

临时绑定到构造函数参数,ref。稍后绑定另一个对它的引用ref_m,不会延长生命周期。如果是这样,您将在堆栈上有一个对象,只要它绑定到的引用成员就必须持续存在,该引用成员可以在堆上分配,因此编译器将无法在构造函数返回时展开堆栈。

收到警告会很好,但编译器并不完美,有些事情很难警告。临时是在与它绑定到引用的位置不同的上下文中创建的,因此编译器只能判断是否打开了 inlinging 或一些巧妙的静态分析。

于 2013-03-20T02:02:44.483 回答
9

C++ 标准规定:

第二个上下文是引用绑定到临时的。引用绑定到的临时对象或作为临时对象绑定的子对象的完整对象的临时对象将在引用的生命周期内持续存在,除非下面指定。 临时绑定到构造函数的 ctor-initializer (12.6.2) 中的引用成员将持续存在,直到构造函数退出。临时绑定到函数调用 (5.2.2) 中的引用参数将一直持续到包含调用的完整表达式完成为止。

注意:顺便说一下,这是重复的(1 , 2),你应该更好地搜索,下次...... :)

于 2013-03-20T02:05:51.287 回答