繁体   English   中英

const引用数据成员绑定到在构造函数中临时初始化该引用

[英]const reference data member bound to a temporary initializing that reference in a constructor

考虑以下代码:

#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对此有何说法?

常量引用不会延长班级,时期的临时人员的寿命。 就是这样。 他们只在Foo const& f = Foo(); foo返回的是按值,仅此而已。

§12.2 [class.temporary]

p4在两种情况下,临时变量在与完整表达式末尾不同的位置被销毁。 [...]

p5第二种情况是引用绑定到临时项时。 引用所绑定的临时对象或作为与该临时对象所绑定的子对象的完整对象的临时对象在引用的生存期内一直存在,除非以下指定。 在构造函数的ctor-initializer(12.6.2)中,绑定到引用成员的临时绑定将一直存在,直到构造函数退出为止

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

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

尝试更改为:

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

你会得到:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM