假设我有一个相当大的类Matrix
,我已经重载了operator==
以检查是否相等:
bool operator==(Matrix &a, Matrix &b);
当然我通过引用传递Matrix对象,因为它们太大了。
现在我有一个方法Matrix::inverse()
,它返回一个新的Matrix对象。现在我想在比较中直接使用逆,如下所示:
if (a.inverse()==b) { ... }`
问题是,这意味着inverse方法需要返回对Matrix对象的引用。两个问题:
由于我只是在这次比较中使用该引用,这是内存泄漏吗?
如果在inverse()方法中返回的对象属于boost :: shared_ptr,会发生什么?方法退出后,shared_ptr将被销毁,对象不再有效。有没有办法返回对属于shared_ptr的对象的引用?
答案 0 :(得分:5)
您无需从inverse()
方法返回引用。返回对象本身。编译器将创建一个临时引用以传递给相等运算符,并且该引用将在运算符返回后立即超出范围。
回答你的问题是否是内存泄漏。
取决于您将从inverse()
返回该对象的位置。如果要返回对堆上分配的对象的引用,如下所示:
Matrix& inverse()
{
Matrix* m = new Matrix();
return *m;
}
那么这肯定是一个泄漏。的确,你永远不会释放那段记忆,是吗?
如果您要返回对堆栈分配对象的引用,请执行以下操作:
Matrix& inverse()
{
Matrix m;
return m;
}
然后我不会说这是泄密......相反,这是一次崩溃。一般保护错误,如果你愿意的话。或者内存损坏。或者是噩梦中的其他东西。不要这样做。永远。 当函数返回时,堆栈分配的对象超出范围,并且回收该内存。但更糟糕的是,它被回收用于调用其他函数,并分配这些函数的局部变量。因此,如果你保留对堆栈分配对象的引用,那么你几乎搞砸了。
最后,您可以为该Matrix使用某种自定义存储,如下所示:
static Matrix _inversed;
Matrix& inverse()
{
_inversed = ...
return _inversed;
}
从技术上讲,这不会构成泄漏或崩溃。但你真的不想这样做,因为从inverse()
方法的签名中不清楚它实际上是否返回对共享实例的引用,这将使得它很容易忘记这一点,并且弄乱那些“反转”的矩阵,弄乱你的数据。