:より転載https://blog.csdn.net/u010700335/article/details/39830425
深いコピーと浅いコピー::2つの方法でC ++のクラスのコピークラス割り当て等号が表示されたら、コピー機能を呼び出します
:二つの違い コピーコンストラクタを表示する場合には、未定義の1は、システムはデフォルトのコピー機能を呼び出します-浅いコピーである、それは部材1コピーずつを完了することができます。NOの場合、ポインタデータメンバない、浅いコピーが可能であるが、ポインタデータメンバがある場合、単純な浅いコピー場合、ポインタの2つのタイプがときにオブジェクトの終了、同じアドレスを指し2つのコールデストラクタ、サスペンションの現象につながるポインタ、従って、このときは、ディープコピーでなければなりません。 差分ディープコピーと浅いコピー2は、ディープコピーがそれ以外の場合は、サスペンション・ポインタの問題を解決するように、ヒープメモリにデータを格納するために適用されるにあります。データメンバポインタがあるときに一言で言えば、あなたは深いコピーを使用する必要があります。
2の例で説明しました
C ++のデフォルトコピーコンストラクタは浅いコピーされて 作成するオブジェクトにそのようなオブジェクトを使用しているときに、そのコピーコンストラクタを提供せずにクラスを設計していない場合は浅いコピーは、オブジェクトのデータメンバ間の単純な割り当てであります割り当てプロセスは、以下のような簡易コピーを、実行された場合:
クラスA { パブリック: (INT _data):データ(_data)} { (){} プライベート: INT データ; }; int型のmain() { A(5)、A = B; // のみデータメンバ割り当ての間 }
シャローコピー文b.data = 5が完了した後に行われる;これは、Bは=で いない他のオブジェクトリソース場合(例:ヒープ、ファイル、システムリソースなど)、深い浅いコピーは何の違いをコピーしていません、 しかし、これらのリソースのオブジェクト、例:
クラスA { パブリック: (int型_size):サイズ(_size) { データ = 新しい新しい INT [サイズ]; } // もし、請求いくつかの動的に割り当てられたメモリ A(){}; 〜A() { 削除[]データ; } // 解放資源デストラクタ プライベート: INT * データ; int型のサイズ; } int型のmain() { A(5、A = B;)// なお、A }
B =浅いコピー実行プロセスように、コピーコンストラクタクラスAは、コンパイラによって生成されるので、ここで、B =、未定義の動作になります。私は浅いコピーのようなデータオブジェクト間の単純な割り当てで言った: ; b.size = a.size b.data = a.data; //おっと! ここで、Bとヒープへのポインタへのデータポインタ同じメモリ、動的に割り当てられたデストラクタが再び解放されたとき、これは順番にメモリを介して放出された、解放およびBデストラクタ、点B第一のデータメモリ。その結果、解放するために2回以上同じ部分を実行するために動的メモリを定義されていないので、メモリリークやクラッシュにつながります。 そこでここでは、深いコピーは、オブジェクトのコピーが(などヒープ、ファイルシステム、など)他のリソースへの参照を持っている場合を指し、この問題を解決するために、深いコピーを必要とする、開いている別のオブジェクト(参照はポインタまたは参照であってもよいです)新しいリソースではなく、オブジェクトのコピーは、単純な代入した参照または引用した他のリソースへのポインタを持っています。以下のような:
クラスA { パブリック: (int型_size):サイズ(_size) { データ = 新しい新しい INT [サイズ]; } // もし、請求いくつかの動的に割り当てられたメモリ A(){}; (CONST A&READ_A):サイズ( _A.size) { データ = 新しい新しい int型[サイズ]; } // 深いコピー 〜A() { 削除[]のデータを; } // 解放資源デストラクタ プライベート: int型 * データ; INTのサイズ; } int型のmain() { A(5)、A = B; //は、これは問題ありません }
概要:オブジェクトをコピーするときにオブジェクト参照をコピーする必要がある場合は、深いと浅いコピーコピー差がオブジェクト参照状態で他のオブジェクトを含むある、オブジェクトは、それはそれ以外の場合は浅いコピーである、ディープコピーです。