2017-08-25 85 views
1

当运行上的gcc 8以下代码(https://wandbox.org/,用 “克++ prog.cc -Wall -Wextra -std = C++ 1Z”):C++结合参考构件构造符参数

#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初始化器中的引用成员是不合格的。 [实施例:

结构A {

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

const int的& V;

};

末端示例]

+1

你混了在字符串'〜B':如果它是一个副本,说这通常破坏,如果没有,说是复制破坏 –

+0

那么什么是问题呢?在修复之后,你认为在施工/破坏顺序方面有什么错误? –

+0

现在订单看起来不错。然而,问题仍然是标准是否说明了绑定成员对构造函数参数的引用。 – user42768

回答

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

+0

我对我的错误表示歉意。是的,现在订单似乎是正确的。但是,该标准是否提及了有关绑定成员引用的构造函数参数? – user42768

+0

当然,没问题。在看到您的答案之前,我通过@king_nak收到的评论更正了我的问题。 – user42768

+0

我发现这个:http://eel.is/c++draft/basic.life#7。我认为它解释了当引用一个生命周期结束的对象时会发生什么。 – user42768