我试图用C ++来讨论范围。请考虑以下事项:
class C
{
int i_;
public:
C() { i_ = 0;}
C(int i) { i_ = i; }
C(const C &c) {
i_ = c.i_;
cout << "C is being copied: " << i_ << endl;
}
int getI() { return i_; }
~C() {cout << "dstr: " << i_ << endl;}
};
class D
{
C c_;
public:
void setC(C &c) { c_ = c; }
int getC_I() { return c_.getI(); }
};
void Test(D &d)
{
C c(1);
d.setC(c);
//here c is going out of scope, surely it will be destroyed now?
}
int main()
{
D d;
Test(d); //this sets value of c_ to the local variable in Test.
//Surely this will be invalid when Test returns?
int ii = d.getC_I();
cout << ii << endl;
}
运行此程序输出:
dstr:1
1
dstr:1
显然,第一个析构函数调用发生在Test中,另一个发生在程序终止并且d被销毁时。
所以我的问题是:c被复制到哪里了?我的推理有问题吗?我要问的一般问题是:有一个成员函数可以安全地获取一个对象的引用,然后将它存储在一个成员变量中吗?
非常感谢你的帮助。
答案 0 :(得分:2)
c被复制到哪里?
当您执行c_ = c;Where was c copied?
时,您正在operator=
上致电c_
,c
会将c_
的内容复制到c_
。
如果{{1}}也是引用,则不会复制任何内容,并且程序会导致错误,就像您期望的那样。
答案 1 :(得分:2)
C被复制到这里:
void setC(C &c) { c_ = c; }
如果您想存储引用,那么您的成员变量c_
也应该是一个引用。如果您要存储引用,那么您必须小心传入的变量的生命周期。
答案 2 :(得分:2)
您的代码现在很好。 D::c_
的类型为C
,而不是C &
。您的SetC
接受对C的引用,并将该引用引用的值分配给C::c_
,因此您拥有的是具有相同值的完全独立的C
对象。由于您在d
中创建了自动存储时长main
,因此在c_
退出之前,它和main
一部分仍然有效。