【问题标题】:Reference parameter lifetime参考参数寿命
【发布时间】:2011-02-01 14:53:28
【问题描述】:

鉴于以下情况:

class ParamClass {...};

class MyObject {
public:
    void myMethod(ParamClass const& param) { _myPrivate = param; }

private:
    ParamClass _myPrivate;
}

[...]

MyObject obj;

void some_function(void)
{
    ParamClass p(...);
    obj.myMethod(p);
}

在对象 p 的生命周期结束时 _myPrivate 会发生什么? 编辑:我仍然可以使用 _myPrivate 访问对象 p 的副本吗?

谢谢!

【问题讨论】:

标签: c++ object-lifetime


【解决方案1】:

由于_myPrivate 不是引用,在赋值_myPrivate = param 中,它的值将从引用param 指向的任何地方复制过来,在这种情况下是局部变量psome_function()

所以如果ParamClass的赋值操作符实现正确,代码应该没问题。

我仍然可以使用 _myPrivate 访问对象 p 的副本吗?

有了上述警告,是的。但准确地说,_myPrivate 不能用于访问p 的副本;它一个变量,其中包含(现已灭绝的)p 中的数据副本。

【讨论】:

    【解决方案2】:

    myMethod 中,您调用ParamClass 的赋值运算符,默认情况下会按位复制对象(您可以定义自己的运算符)。所以你创建了一个 p 的副本,它是可以访问的

    【讨论】:

    • 它是逐个成员复制,而不是按位复制
    【解决方案3】:

    引用就像一个对象的别名。引用没有自己的生命周期。要考虑的生命周期是所引用对象的生命周期。

    在您的示例中,_myPrivate 是一个对象,因此 operator= 将复制引用传递的对象 p。 p 将被销毁,参数引用将不引用任何内容,但 _myPrivate,作为副本就可以了。

    如果 _myPrivate 被声明为:

    ParamObject& _myPrivate;
    

    在这种情况下,您最终会得到一个“悬空”引用:未定义的行为:)

    my2c

    【讨论】:

      【解决方案4】:

      看看:

      _myPrivate = param;

      在此语句中,赋值运算符 (ParamClass::operator=) 将 param 引用的对象的每个成员的值复制到 _myPrivate 的成员中。当some_function 返回时,p 从堆栈中移出 - 它消失了。但是_myPrivate 现在包含p 的成员值的副本。

      如果ParamClass 的成员是指向动态分配内存的指针,您必须确保ParamClass::operator= 执行深度复制,否则您可能会遇到悬空指针问题 - ParamClass's析构函数可能会释放该内存,但 _myPrivate 将有一个仍然指向它的成员!

      【讨论】:

        猜你喜欢
        • 2017-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-18
        • 2011-01-31
        相关资源
        最近更新 更多