C ++将引用成员绑定到构造函数参数

时间:2017-08-25 11:39:29

标签: c++ class oop reference lifetime

在gcc 8(https://wandbox.org/上运行以下代码时,使用“g ++ prog.cc -Wall -Wextra -std = c ++ 1z”):

#include <iostream>

class B{
public:
    B(): copy(false){ std::cout << "B-constructed" << std::endl;}
    B(const B& b): copy(true){ std::cout << "B-copy-constructed" << std::endl; }
    ~B(){ std::cout << (copy?"B-destructed":"B-(copy)-destructed") << std::endl;}

    bool copy;
};

class A{
public:
    A(B b): bref(b){std::cout << "A-constructed" << std::endl;}
    ~A() {std::cout << "A-destructed" << std::endl;}
    B &bref;
};


void f(){
    B b;
    A a(b);

    std::cout << "f over" << std::endl;
}

int main()
{
    f();

    std::cout << "main over" << std::endl;
    return 0;
}

产生以下输出:

B-constructed
B-copy-constructed
A-constructed
B-destructed
f over
A-destructed
B-(copy)-destructed
main over

物体破坏的顺序似乎不寻常。就好像构造函数参数的生命周期被扩展了一样。标准是否说明了绑定成员对构造函数参数的引用?

我不认为该标准的引用适用,因为参数不是临时对象(但我不知道“临时表达式”的定义):

  

绑定到mem-initializer中的引用成员的临时表达式格式不正确。 [例如:

     

struct A {

     

A():v(42){} //错误

     

const int&amp; V;

     

};

     

-end example]

1 个答案:

答案 0 :(得分:1)

您的析构函数存在逻辑错误,因为您打印时copy出错时会导致副本被破坏。

改变这个:

~B(){ std::cout << (copy?"B-destructed":"B-(copy)-destructed") << std::endl;}

到此:

~B(){ std::cout << (copy?"B-(copy)-destructed":"B-destructed") << std::endl;}

现在输出:

B-constructed
B-copy-constructed
A-constructed
B-(copy)-destructed
f over
A-destructed
B-destructed
main over

漂亮而清晰(Order of member constructor and destructor calls)。

标准是否说明了绑定成员对构造函数参数的引用?

  

同样,在对象的生命周期开始之前但在之后   对象占用的存储空间已被分配,或之后   对象的生命周期已经结束,在存储之前就已经存在了   对象占用被重用或释放,任何引用的glvalue   可以使用原始对象,但仅限于有限的方式。对于一个对象   正在建设或破坏,见[class.cdtor]。否则就是这样   glvalue是指分配的存储空间   ([basic.stc.dynamic.deallocation]),并使用的属性   不依赖于其值的glvalue是明确定义的。

Source