昨日のシンプレックスを満たすことが、クラスはポインタ型が含まれている最初の深いコピーと浅いコピーを見て前に、コピーコンストラクタにあるもの、代入演算子を実装し、コンストラクタをコピーする必要があり、プログラミングの仕様、の話しました違い。まず、コンパイラが自動的にコンストラクタの1を呼び出しますが、知られているオブジェクトの場合は、コピーされる考える - ユーザーが定義されていない場合はコピーコンストラクタは、デフォルトのコピーコンストラクタを呼び出します、コンストラクタをコピーします。
例を見て、生徒、学生の人口データと名のメンバーのクラスがあります:
書式#include <iostreamの> 使用して、名前空間STD; クラスの学生 { プライベート: int型NUM; 文字*名; 公共: 学生(); 〜学生(); }; 学生::学生() { 名=新しい新しいCHAR(20)で、 COUT << "学生" << ENDL; } 学生学生::〜() { COUT << "学生〜" <<(INT)名<< ENDL; ;名を削除 名= NULL; } int型のmain() { {/ /部分オブジェクト便利なテストにS1とS2のブレースを聞かせて 学生S1; 学生は、S2(S1); //ターゲットコピー } システム( "PAUSE")を、 0を返します; }
結果:問題を引き起こす可能性があり、コンストラクタの呼び出し、二回と呼ばれるデストラクタ、同じメモリの意義の範囲内で二つのオブジェクトポインタのメンバー、?名前のポインタは、メモリが割り当てられていますが、プログラムメモリの終わりに二回解放された、クラッシュ!
これは、オブジェクトをコピーする際、デフォルトのコピーコンストラクタが呼び出されます、我々はコピーコンストラクタの独自の定義を持っていないビルドシステムに起因して、浅いコピーです!すなわち、ポインタはメモリ空間への同じポインタの2つのコピーの名前の後に表示されます。
ポインタのメンバーを含むオブジェクトをコピーすることができたときにオブジェクトポインタメンバーのコピーは、このようにメモリリークを避け、独自のメモリ空間、すなわち深いコピーを持つようにそのため、あなたは、あなた自身のコピーコンストラクタを定義する必要があります。
例としては、コピーコンストラクタ独自の定義を追加します。
書式#include <iostreamの> 名前空間stdを使用。 クラスの学生 { プライベート: int型NUM; CHAR *名前。 公共: 学生(); 〜学生(); 学生(CONST学生&S); //拷贝构造函数、CONST防止对象被改变 }。 学生::学生() { 名前=新しいCHAR(20)。 裁判所未満<< "学生" <<てendl; } 学生::〜学生() { coutの<< "〜学生" <<(int型)名<<てendl; 名前を削除します。 名前= NULL; } 学生::学生(CONST学生&S) { 名前=新しいCHAR(20)。 memcpyの(名前、s.name、strlenを(s.name)); coutの<< " メインINT() { {//部分オブジェクトに便利試験ブレースS1及びS2を行う 学生S1を、 スチューデントS2(S1); //は、ターゲットコピー } システム( "PAUSE")を、 0を返します; }
結果:二回、コンストラクタ、カスタムコピーコンストラクタ、デストラクタを呼び出します。ポインタのメンバーは、2つの異なるメモリー・オブジェクトに言及しました。
概要:浅いコピーだけでポインタをコピーし、同じメモリ空間のコピーを指す2つのポインタが、唯一のディープコピーポインタがコピーされ、ポインタの内容をコピーする、ポインタが深いコピーに2つの異なるアドレスを指していますポインタ。
いくつかの単語を言う:
:ポインタメンバーがオブジェクトに存在する場合には、オブジェクトをコピーすることに加えて、ときにカスタムコピーコンストラクタ考慮する必要があり、また、次の2つの状況を検討すべき
パラメータは、パラメータにオブジェクト引数の関数である場合には1をそれは、自動的にシステムのコピーコンストラクタによって、実際にオブジェクト引数のコピーであり、
関数はオブジェクトの値を返すとき2.、オブジェクトが実際に関数オブジェクト、関数呼び出しの戻り値のコピーです。3.問題の本質は浅いコピーであるが、デストラクタがのstd :: shared_ptrのを使用して、ヒープメモリを複数回解放もたらし、この問題の完璧な解決策になることができます。