【发布时间】:2017-08-25 11:39:28
【问题描述】:
在 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 中的引用成员的临时表达式格式不正确。 [ 例子:
结构 A {
A() : v(42) { } // 错误
const int& v;
};
——结束示例]
【问题讨论】:
-
你把
~B中的字符串弄混了:如果是副本,说它是正常破坏的,如果不是,说它是复制破坏的 -
那么问题是什么?在修复之后,您认为构建/销毁的顺序有什么问题?
-
现在订单看起来不错。然而,剩下的问题是标准是否说明了将成员引用绑定到构造函数参数。
-
eel.is/c++draft/basic.life#7 是否解释了这种行为(绑定到生命周期已结束的对象的引用)?
标签: c++ class oop reference lifetime