分配通过引用传递给成员变量的值(在C ++中)

时间:2010-06-25 22:11:40

标签: c++ scope pass-by-reference

我试图用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被复制到哪里了?我的推理有问题吗?我要问的一般问题是:有一个成员函数可以安全地获取一个对象的引用,然后将它存储在一个成员变量中吗?

非常感谢你的帮助。

3 个答案:

答案 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一部分仍然有效。