コピーコンストラクターは、特殊なコンストラクターで、オブジェクトを構築するのに、
それと同じ型の別のオブジェクトのコピーとして作る、例えば次のComplexオブジェクトを宣言したとしょう。

この時、Complexの第2のインスタンス,c1のコピーとして実体化することができる。

多くの場合、コンストラクターは、プログラマーが宣伝しなければC++が自動的に提供
してくれる。こののコピーコンストラクターは、元のオブジェクトから新しいに、すべての
メンバーをコピーする。Complexの場合、それでまったく
問題はない。c2.mRealとc2.mImaginaryは、それぞれに対応するc1のメンバーから直接される
しかし、クラスデータへのポインタを含む、DynamicArrayなどの場合、メンバーデータを
直接的にコピーしても望ましい結果は得られない。次のコードを実行すると、どうなるだろうか。

デフォルトコピーコンストラクターでは、mArrayのポインタ群が直接的にコピーされるだけ
で、動的に割り当てられらた配列そのものはコピーされない。つまり、このあとでotherArray
を書き換えたら、同時にarrayも書き換えることになる!浅いコピー(shallow copy)と呼ばれる、
この振る舞いの問題を下の図を示す。

このように、デフォルトのコピーコンストラクターの浅いコピーでは不十分な時は、次のように、
独自のコピーコンストラクターを宣言しなければならない。

このコピーコンストラクターへの唯一の引数が、このクラスの、もう1つのインスタンスへ
のconst参照であることに注目しょう。この実装は、新しい配列を割り当ててから、その
データをもう1つのDynamicArrayからコピーしている。これで2つのオブジェクトは、それぞれ別
に、動的に割り当てられ配列を持つことになるので、深いコピー(deep copy)になっている。
一般的に、データを動的に割り当てるクラスは、次のメンバー関数を実装すべきだ。
❑動的に割り当てたを解放するデストラクター
❑深いコピーを実装するコピーコンストラクター
❑深いコピーを実装する代入演算子
これら3つの関数の、どれかを実装する必要がある時は、この3つをすべて実装するべきだ。
C++では、これがよく問題になるので、忘れないように3つの法則(rule of three)
という名前が付いてる。
【戻る】