C ++でコピーコンストラクターと代入演算子を記述するためのチェックリスト

StackOverflow https://stackoverflow.com/questions/214891

質問

例外の安全性の維持、メモリリークの回避などのために、コピーコンストラクタと割り当て演算子がC ++で実行する必要があるタスクのリストを作成してください。

役に立ちましたか?

解決

まず、コピーを本当にサポートする必要があることを確認してください。ほとんどの場合そうではないので、両方を無効にするのが良いでしょう。

場合によっては、ポリモーフィックな階層からクラスを複製する必要があります。その場合は、割り当て演算子を無効にし、(保護された?)コピーコンストラクタを記述し、仮想clone()関数を提供します。

それ以外の場合、値クラスを記述している場合、Coplienの直交正準形の土地に戻ります。簡単にコピーできないメンバーがいる場合は、コピーコンストラクター、デストラクター、代入演算子、およびデフォルトコンストラクターを提供する必要があります。このルールは改良できます。たとえば、ビッグツーの法則

割り当て演算子に関するC ++ FAQも参照することをお勧めします。 、および copy-and-swapイディオムおよび GOTW で。

他のヒント

コンパイラ生成バージョンは、ほとんどの状況で機能します。

オブジェクトにRAWポインター(RAWポインターを持たないための引数)が含まれている場合、問題について少し難しく考える必要があります。 RAWポインターがあります。2番目の質問は、ポインターを所有していますか(削除されていますか)。その場合、4のルールを適用する必要があります。

1つ以上のRAWポインターを正しく実行することはますます難しくなります(複雑さの増加も直線的ではありません[ただし、これは観察的であり、そのステートメントをバックアップする実際の統計はありません)。したがって、複数のRAWポインターがある場合は、それぞれを独自のクラス(何らかの形のスマートポインター)でラップすることを検討してください。

4のルール:オブジェクトがRAWポインターの所有者である場合、次の4つのメンバーを定義して、メモリ管理を正しく処理することを確認する必要があります。

  • コンストラクター
  • コンストラクタのコピー
  • 割り当て演算子
  • デストラクタ

これらの定義方法は状況によって異なります。ただし、次の点に注意してください:

  • デフォルトの構築:ポインターをNULLに設定
  • コピーコンストラクター:コピーとスワップのアイデアを使用して、「強い例外保証」に提供します
  • 割り当て演算子:自分への割り当てを確認する
  • デストラクタ:デストラクタから伝播する例外から保護します。

これを読んでみてください。

http://www.icu-project.org/docs /papers/cpp_report/the_anatomy_of_the_assignment_operator.html

代入演算子の非常に優れた分析

ここでは安全に例外についての見当がつかないが、私はこのようにしている。テンプレート化された配列ラッパーであると想像してみましょう。役に立てば幸いです:)

Array(const Array& rhs)
    {
        mData = NULL;
        mSize = rhs.size();
        *this = rhs;
    }

    Array& operator=(const Array& rhs)
    {
        if(this == &rhs)
        {
            return *this;
        }

        int len = rhs.size();

        delete[] mData;

        mData = new T[len];

        for(int i = 0; i < len; ++i)
        {
            mData[i] = rhs[i];
        }

        mSize = len;

        return *this;
    }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top