深浅コピーの私見

2559 ワード

自分がstring類を実現することを学ぶ時先生は深いコピーと浅いコピーを説明したことがあって、最近STLを学ぶのはまたこの問題に出会って、自分の前の理解があまり深くないことに気づいて、この文章を書いてみんなと自分の再理解を分かち合って、収穫があることを望みます.
≪ライト・コピー(ビット・コピー)|Raw Copy(BitCopy)|oem_src≫:ソース・オブジェクトとコピー・オブジェクトが同じエンティティを共有することを意味します.参照される変数が異なるだけです(名前が異なります).いずれかのオブジェクトの変更は、別のオブジェクトに影響します.
C++でよく遭遇する例を挙げると、クラスAを定義し、類似A aを使用する.  A a1(a);またはA a 1=a;の場合、カスタムコピーコンストラクタがないため、C++コンパイラは自動的にデフォルトのコピーコンストラクタを生成します.このデフォルトのコピーコンストラクタは、「値コピー」(深コピー)ではなく「ビットコピー」(浅いコピー)を採用しています.クラスにポインタ変数が含まれている場合、デフォルトのコピーコンストラクタでは必ずエラーが発生します.浅いコピーは、ポインタのコピーにすぎません.コピー後の2つのポインタが同じメモリ領域を指しているため、一連の問題が発生します.
では、浅いコピーはいったいどんな問題を引き起こすのだろうか.
First-->浅いコピーはポインタをコピーしただけで、2つのポインタが同じアドレスを指すようにします.これにより、オブジェクトが構造関数の呼び出しを終了すると、同じメモリが2回解放され、プログラムがクラッシュします.
Second-->浅いコピーにより、2つのポインタが同じメモリを指し、いずれかの変更が別のメモリに影響します.
Third-->メモリを解放するとき、aを先に解放してからa 1を解放すると、aとa 1が同時に1つのメモリを指しているため、aはすでに解放されているので、その指す空間も使用できなくなり、a 1が解放されるとその空間を操作できなくなり、メモリ漏れを招く.
そのため、これらの問題の発生を防止するために、深いコピーがあります.
深度コピー(値コピー):ソースオブジェクトとコピーオブジェクトが互いに独立しており、いずれのオブジェクトの変更も他のオブジェクトに影響を与えません.
すなわち、深いコピーは、ポインタをコピーするだけでなく、ポインタが指す内容をコピーし、深いコピー後の2つのポインタが異なる空間を指し、浅いコピーによる一連の問題を回避する.
深いコピーを使用してstringのコピー構造関数を実現します.
String(const String &other)  
{     
      int length = strlen(other.m_data);  
      m_data = new char[length + 1];  
      strcpy(m_data, other.m_data);  
}

コピーコンストラクション関数でメンバー変数に新しいメモリ領域が申請されていることがわかります.これにより、2つのオブジェクトのメンバー変数が同じメモリ領域を指さず、プログラムの実行がスムーズになります.
デフォルトのコピーコンストラクション関数を使用すると、次のコードを参照してください.
class A  
{  
    public:  
        A()      //     ,p            
        {  
            m_data = new char(100);  
            printf("      
");           }           ~A()     //  ,            {               if(m_data != NULL)               {                   delete m_data;                   m_data = NULL;                   printf("
");               }           }       private:           char *m_data;     //     };      int main()   {       A a;       A b(a);   //         return 0;   }

コピーコンストラクタがないため、コンパイラのデフォルトのコピーコンストラクタ、A b(a);オブジェクトのプロファイルを行うと、同じメモリ領域が2回解放され、メモリが漏洩します.
これにより、深いコピーと浅いコピーの違いを簡単にまとめることができます.
浅いコピーとは、オブジェクト内の数値タイプのフィールドを新しいオブジェクトにコピーすることであり、オブジェクト内の参照タイプのフィールドは、ターゲットオブジェクトにコピーされた参照の1つを指します.ターゲットオブジェクトの参照フィールドの値を変更すると、元のオブジェクトに反映されます.つまり、元のオブジェクトの対応するフィールドも変更されます.深いコピーは浅いコピーとは異なり、参照の処理では、新しいオブジェクトに新しいフィールドと元のオブジェクトの対応するフィールドが同じ(内容が同じ)フィールドが作成されます.つまり、この参照と元のオブジェクトの参照は異なり、元のオブジェクトのこのフィールドを変更するときに元のオブジェクトの対応するフィールドの内容には影響しません.