1

假设我有一个相当大的 class Matrix,并且我已经重载operator==以检查相等性,如下所示:

bool operator==(Matrix &a, Matrix &b);

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

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

if (a.inverse()==b) { ... }`

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

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

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

4

1 回答 1

5

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


回答您的问题是否是内存泄漏。

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

    Matrix& inverse()
    {
        Matrix* m = new Matrix();
        return *m;
    }

那么这绝对是一个泄漏。事实上,你永远不会释放那段记忆,是吗?如果您要返回对堆栈分配对象的引用,如下所示:

    Matrix& inverse()
    {
        Matrix m;
        return m;
    }

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

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

    static Matrix _inversed;

    Matrix& inverse()
    {
        _inversed = ...
        return _inversed;
    }

Technically, this wouldn't constitute a leak or a crash. But you really don't want to do it either, because it's not clear from the signature of the inverse() method that it actually returns a reference to shared instance, which will make it all too easy to forget this, and to fiddle with those "inversed" matrices, screwing up your data.

于 2010-04-25T04:29:28.613 回答