在介紹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指針變量指向的地址。
總結:
當類中無需申請動態資源時,淺拷貝構造函數能夠很好的工做。當須要申請動態內存時,即類中有指針變量,則須要自定義深度拷貝函數。
表述不當之處,還望各路大神指正。