2

次のクラスを定義しました。

class Action
{
    public: 
    Action(){ _bAllDone = false; }

    void AddMove( Move & m );
    private:
        std::deque<Move> _todo;
        bool _bAllDone;
};

メンバー AddMove は次のように定義されます。

void Action::AddMove( Move & m )
{ 
    _todo.push_back( m ); 
}

この関数への参照引数がない場合、コピー コンストラクターは 2 回呼び出されましたが、参照引数がある場合は 1 回しか呼び出されませんでした。コピー コンストラクターを 2 回ではなく 1 回だけ呼び出すのは、参照引数を使用する正当な理由ですか?

4

3 に答える 3

17

STL の deque クラスは、push_back メソッドに渡す要素のコピーを保持することになっています。それが、1 つのコピー コンストラクターの由来です。

addMove() で参照を削除すると、最初にパラメーターのコピーが取得され (したがって、コピー コンストラクターが 1 回呼び出されます)、プッシュバックすると 2 つ目のコピーが取得されます。

コピー コンストラクターの二重呼び出しは無駄が多いため、参照が推奨されます。ただし、要素が変更されないことを呼び出し元に示すために、addMove() のパラメーターを const 参照として宣言する必要があります。このような保証の下では (それを壊さないと仮定して)、心配することなく、オブジェクトのコピーのペナルティを支払うことなく、参照によってオブジェクトを安全に渡すことができます。

于 2009-10-05T20:17:12.727 に答える
4

私には大きな利点のように思えます。多くの追加を繰り返し実行すると、処理が非常に遅くなる可能性があります。実際の作業量は、Move とそのコピー コンストラクターの定義によって異なります。また、小さな変更がパフォーマンスに深刻な影響を与える可能性があります。いずれにせよ、コピーで渡すと、2 倍の作業が必要になります。

これの全体的な効果は、この操作に全体の処理がどれだけ費やされるかによって異なります。一度やってみれば、決して気付かないでしょう。数千回実行すると、かなりの量になる可能性があります。ただし、一般的な原則として、安全に参照できる場所にデータをコピーすることは避けてください。特に、この場合、特定の明確さや複雑さの問題はありません。遅くするのと同じくらい簡単に速くすることができます。遅くする?

于 2009-10-05T20:26:51.117 に答える
0

それは参照である必要があります。そうしないと、引数の不要な (そして潜在的に間違った) コピーが発生します。そうしないとconst、呼び出し元を不必要に制限することになります。

また、先頭にアンダースコアが付いた名前は言語実装に予約されているため、プログラムは実際には「未定義」であることにも注意してください。

HTH

于 2009-10-05T21:22:49.323 に答える