在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]
答案 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是明确定义的。