C++拷貝構造函數:淺拷貝與深拷貝


  在介紹C++淺拷貝與深拷貝之前,我們先引出C++的拷貝構造函數。

  C++拷貝構造函數是一種特殊的構造函數,其形參是本類對象的引用。用於在建立一個新的對象時,使用一個已經存在的對象來初始化這個新對象。因為拷貝構造函數時特殊的構造函數,所以其沒有返回值類型,且名稱與類名相同;該函數只有一個參數,即此類對象的引用;所有類都必須有一個拷貝構造函數,如果沒有自動以拷貝構造函數,系統會自動產生一個默認拷貝構造函數。

  自定義拷貝構造函數的一般形式為:

    類名::類名(const 類名& 對象名)

        {

          函數體;

        }

  淺拷貝:在進行初始化的過程中僅進行簡單的數據成員賦值。

  例如:

    class A{

      private:

        int a;

      public:

        A(int ta):a(ta){}

    };

  有如下代碼:

    A a(5);

    A b(a);

  程序執行b(a)時,執行操作:b.a=a.a;與系統自動產生的拷貝構造函數:

    A::A(const A& t){this->a=t.a;}

  執行相同內容。完整代碼如下:

      

 

  執行結果為:

    

 

  從結果中我們發現,我們通過對象a初始化的對象b中,數據元素與a中完全相等,甚至指針指向的地址都相同。不難看出,在a初始化b過程中只是進行了簡單的值傳遞,並沒有為b中的p申請新的堆內存空間。即兩個對象的指針指向同一個地址,這也就意味着此地址將被釋放兩次,顯然是不可取的。這一點由輸出結果中b中*p的值異常便可看出。為了解決此問題,我們需要深拷貝。

  深拷貝:當類中有指針類型元素,需要申請堆內存空間時,為新的指針分配新的內存空間。(不可進行簡單的值傳遞)

  這時,需要我們自定義拷貝構造函數:

    

  此時,重新編譯運行程序,結果為:

    

  此時,雖然對象a已被刪除,對象a仍輸出正常,這是因為在自定義的深拷貝函數中,為新的對象申請了新的空間,而不是令其指向a中p指針變量指向的地址。

  總結:

    當類中無需申請動態資源時,淺拷貝構造函數可以很好的工作。當需要申請動態內存時,即類中有指針變量,則需要自定義深度拷貝函數。

  表述不當之處,還望各路大神指正。

 

 

 

      


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM