【问题标题】:const reference data member bound to a temporary initializing that reference in a constructorconst 引用数据成员绑定到临时初始化构造函数中的引用
【发布时间】:2011-12-09 19:48:03
【问题描述】:

考虑以下代码:

#include <iostream>

struct A {
    const char *name;

    A() : name("A") {
        std::cout << "A()\n";
    }

    virtual ~A() {
        std::cout << "~A()\n";
    }
};

class B {
    const A& a;
public:

    B() : a(A()) {
    };

    void print_data() const {
        std::cout << a.name << '\n';
    }

    ~B() {
        std::cout << "~B()\n";
    }
};

int main() {
    B b;
    b.print_data();
    return 0;
}

GCC 4.4 的输出是:

A() ~A() A ~B()

这对我来说很奇怪。我本来希望 A 的临时实例的副本绑定到 B::a 或该临时实例本身在 ~B() 期间被破坏。

基本上,我认为 B::a 在 b 的生命周期中始终是一个有效的参考。事实上 b.print_data() 显然有效,编译器没有给出任何警告。

标准 c++98/03 对此事有何评论?

【问题讨论】:

  • 我一直不明白这类问题的主要目标是什么。您只需阅读 c++ 参考。另外,您在实际项目中使用这种结构的频率如何?
  • 希望永远不会!大声笑 - 那将是一个破碎的设计。 ;)

标签: c++


【解决方案1】:

持续引用不会延长临时课程的寿命,期间。就是这样。他们只在Foo const&amp; f = Foo(); 中这样做,foo 按值返回,仅此而已。

§12.2 [class.temporary]

p4 在两种情况下,临时对象在与完整表达式结尾不同的点被销毁。 [...]

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

【讨论】:

    【解决方案2】:

    您的代码涉及未定义的行为。当B的构造函数退出(C++03,[class.temporary])时,临时对象被破坏:

    在构造函数的 ctor-initializer (12.6.2) 中临时绑定到引用成员会一直存在,直到构造函数退出。

    尝试更改为:

    B() : a(A()) {
        cout << "B()\n";
    };
    

    你会得到:

    A() B() ~A() A ~B()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-03
      • 2016-09-17
      • 1970-01-01
      • 1970-01-01
      • 2015-04-27
      相关资源
      最近更新 更多