1

かなり大きな classがあり、次のように等価性をチェックするためにMatrixオーバーロードしたとします。operator==

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

もちろん、Matrix オブジェクトは非常に大きいため、参照渡ししています。

Matrix::inverse()これで、新しい Matrix オブジェクトを返すメソッドができました。ここで、次のように、比較で逆を直接使用したいと思います。

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

問題は、逆メソッドが Matrix オブジェクトへの参照を返す必要があることです。2 つの質問:

  1. この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;
    }

それなら、リークとは言いません... 代わりに、クラッシュです。必要に応じて、一般保護違反。またはメモリの破損。または、悪夢からの何か。これをしないでください。これまで。そのようなスタック割り当てオブジェクトは、関数が戻るとスコープ外になり、そのメモリは回収されます。さらに悪いことに、他の関数を呼び出し、それらの関数のローカル変数を割り当てる目的で再利用されます。したがって、スタックに割り当てられたオブジェクトへの参照を保持している場合は、ほとんど失敗します。

最後に、次のように、その Matrix に何らかのカスタム ストレージを使用できます。

    static Matrix _inversed;

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

技術的には、これはリークやクラッシュにはなりません。しかし、メソッドの署名からは、実際に共有インスタンスへの参照を返すことが明確ではないためinverse()、これを忘れてしまい、それらの「逆" 行列、データを台無しにします。

于 2010-04-25T04:29:28.613 に答える