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

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

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

  自定義拷貝構造函數的通常形式爲:指針

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

        {blog

          函數體;內存

        }資源

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

  例如:class

    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指針變量指向的地址。

  總結:

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

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

相關文章
相關標籤/搜索