使用shared_ptrs时返回引用

Vla*_*ala 1 c++ boost reference shared-ptr

假设我有一个相当大的类Matrix,我已经重载operator==以检查是否相等如下:

bool operator==(Matrix &a, Matrix &b);
Run Code Online (Sandbox Code Playgroud)

当然,我通过引用传递Matrix对象,因为它们太大了.

现在我有一个Matrix::inverse()返回新Matrix对象的方法.现在我想在比较中直接使用逆,如下所示:

if (a.inverse()==b) { ... }`
Run Code Online (Sandbox Code Playgroud)

问题是,这意味着inverse方法需要返回对Matrix对象的引用.两个问题:

  1. 由于我只是在这次比较中使用该引用,这是内存泄漏吗?

  2. 如果在inverse()方法中返回的对象属于boost :: shared_ptr,会发生什么?方法退出后,shared_ptr将被销毁,对象不再有效.有没有办法返回对属于shared_ptr的对象的引用?

Fyo*_*kin 5

您无需从inverse()方法返回引用.返回对象本身.编译器将创建一个临时引用以传递给相等运算符,并且该引用将在运算符返回后立即超出范围.


回答你的问题是否是内存泄漏.

取决于你将要从哪里获得你要返回的对象inverse().如果要返回对堆上分配的对象的引用,如下所示:

    Matrix& inverse()
    {
        Matrix* m = new Matrix();
        return *m;
    }
Run Code Online (Sandbox Code Playgroud)

那肯定是泄密.的确,你永远不会释放那段记忆,是吗?如果要返回对堆栈分配对象的引用,如下所示:

    Matrix& inverse()
    {
        Matrix m;
        return m;
    }
Run Code Online (Sandbox Code Playgroud)

然后我不会说这是泄漏...相反,它是一个崩溃.一般保护错误,如果你愿意的话.或者内存损坏.或者是噩梦中的其他东西.不要这样做.永远.当函数返回时,堆栈分配的对象超出范围,并且回收该内存.但更糟糕的是,它被回收用于调用其他函数,并分配这些函数的局部变量.因此,如果你保留对堆栈分配对象的引用,那么你几乎搞砸了.

最后,您可以为该Matrix使用某种自定义存储,如下所示:

    static Matrix _inversed;

    Matrix& inverse()
    {
        _inversed = ...
        return _inversed;
    }
Run Code Online (Sandbox Code Playgroud)

从技术上讲,这不会构成泄漏或崩溃.但是你真的不想这样做,因为从inverse()方法的签名中不清楚它实际上是否返回对共享实例的引用,这将使得它很容易忘记这一点,并摆弄那些"反转的" "矩阵,搞砸你的数据.