「クラス関連」

コピーコンストラクター

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



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



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



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



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



 このコピーコンストラクターへの唯一の引数が、このクラスの、もう1つのインスタンスへ
const参照であることに注目しょう。この実装は、新しい配列を割り当ててから、その
データをもう1つのDynamicArrayからコピーしている。これで2つのオブジェクトは、それぞれ別
に、動的に割り当てられ配列を持つことになるので、深いコピー(deep copy)になっている。
 一般的に、データを動的に割り当てるクラスは、次のメンバー関数を実装すべきだ。

動的に割り当てたを解放するデストラクター
深いコピーを実装するコピーコンストラクター
深いコピーを実装する代入演算子

 これら3つの関数の、どれかを実装する必要がある時は、この3つをすべて実装するべきだ。
C++では、これがよく問題になるので、忘れないように3つの法則(rule of three)
という名前が付いてる。

【戻る】