在下面的代码中,当我将一个未命名的A变量传递给ctor时B,该变量在该行之后被破坏.根据这个答案:
临时对象在它们所属的完整表达结束时被销毁.完整表达式是不是某个其他表达式的子表达式的表达式.通常这意味着它结束于
; (or ) for if, while, switch etc.)表示语句的结尾.
我明白了,但是如果它被破坏了,那么这个类怎么能B知道它mamber_a变量的值呢?我知道复制的ctor A是enver.这怎么可能?
#include <iostream>
using namespace std;
class A
{
int sign;
A();
const A & operator=(const A &);
public:
A(int x) : sign(x) {
cout << "A ctor : " << sign << endl;
}
void WriteA() const {
cout << sign << endl;
}
~A() {
cout << "A dtor : " << sign << endl;
}
A(const A &) {
cout << "A copied : " << sign << endl;
}
};
class B
{
int sign;
const A & member_a;
public:
B(const A & aa , int ww ) : sign (ww) ,member_a(aa) {
cout << "B ctor : " << sign << endl;
}
void WriteB() const {
cout << "Value of member_a :";
member_a.WriteA();
}
~B() {
cout << "B dtor : " << sign << endl;
}
};
int main() {
A a(10);
B b1(a,1);
b1.WriteB();
B b2(A(20),2);
b2.WriteB();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
A ctor : 10
B ctor : 1
Value of member_a :10
A ctor : 20
B ctor : 2
A dtor : 20
Value of member_a :20 // Object A was destructed. Where does this 20 come from?
B dtor : 2
B dtor : 1
A dtor : 10
Run Code Online (Sandbox Code Playgroud)
你有一个C++的棘手部分
member_a具有值20的纯粹机会.您正在将未经定义的行为视为已被指定的内容.
当类保留对外部对象的引用时,程序员有责任确保对象的生命周期比所引用的对象持续更长时间.在这种情况下,当你调用member_a.WriteA();一个对象已被销毁,因此你正在访问可能不属于你的内存(在这种情况下,它恰好位于附近没有被覆盖的位置(完全偶然)) .
如果要保留对对象的引用.您可以保留const引用,但有时最好使参数成为普通引用,这样您就不会意外地传递临时值(这并不总是有效,因为您可能需要通过引用传递const对象).