【问题标题】:Const reference as class memberconst 引用作为类成员
【发布时间】:2013-03-08 23:14:11
【问题描述】:

即使这个话题在这里讨论过很多次,我也找不到关于我的具体案例的结论性解释。 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;
}

【问题讨论】:

  • 最后一行根本没有创建对象。它正在声明一个函数。见en.wikipedia.org/wiki/Most_vexing_parse
  • @OliCharlesworth 哦,开枪。我担心这个例子很愚蠢:(请看我更新的那个,应该更接近我的真实情况。这一次,我不认为应该有任何令人烦恼的解析问题。
  • @NayanaAdassuriya 哪个test2?我重写了我最初的例子,因为我没有考虑足够的想法。
  • @carleeto 是的,Haroogan 已经链接了它。谢谢。

标签: c++ class reference constants member


【解决方案1】:

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

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

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

【讨论】:

  • 哦,该死的。我没有想到它会绑定到函数参数,而不是内部成员。感谢您指出这一点。
  • 即使你在子构造函数中创建了一个临时的,例如ref_m(RefTest("")) 那么它不会将生命周期延长到构造函数的末尾,原因与临时变量位于构造函数的堆栈框架中并且必须在该函数返回时销毁相同的原因。该标准明确指出:“在构造函数的 ctor-initializer (12.6.2) 中,临时绑定到引用成员的状态一直存在,直到构造函数退出。” 12.2 [class.temporary]
  • 确实如此。然后我在这里看到的与我的问题相关的大多数答案都是误导性的。我的印象是,如果我为 const 引用分配一个临时对象,那么该对象只会在引用超出范围后被销毁,而不是临时对象本身。
【解决方案2】:

C++ 标准规定:

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

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

【讨论】:

  • 是的,现在很清楚了。感谢您对标准的引用。
  • 感谢编辑中的参考。关于这个主题的问题太多了,现在我可以理解为什么了……他们中的大多数给我的印象是,将临时分配给 const 引用会延长它的寿命,直到引用超出范围。
猜你喜欢
  • 2020-09-14
  • 2020-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多