淺拷貝與深拷貝之間的區別
阿新 • • 發佈:2019-01-28
淺拷貝就是在類是以複製方式建立物件的時候,或者在變數進行復制的時候,沒有設定自定義的拷貝建構函式或過載等號運算子的拷貝函式,導致對變數中的所有進行拷貝,包括指標,即指標只拷貝地址,不會再為指標變數申請記憶體。
程式碼如下:
#include<stdio.h> class test { public: int num; int *point; }; int main() { test t1; t1.point=new int; scanf("%d",&t1.num); test t2=t1; printf("%d %d %p %p\n",t1.num,t2.num,t1.point,t2.point); t2=t1; printf("%d %d %p %p\n",t1.num,t2.num,t1.point,t2.point); return 0; }
結果如下:
即兩個指標指向了相同的地址,那這樣有什麼問題呢?別忘了,我們還沒有設定解構函式。
#include<stdio.h> class test { public: int num; int *point; ~test() { delete point; } }; int main() { test t1; t1.point=new int; scanf("%d",&t1.num); test t2=t1; printf("%d %d %p %p\n",t1.num,t2.num,t1.point,t2.point); t2=t1; printf("%d %d %p %p\n",t1.num,t2.num,t1.point,t2.point); return 0; }
我們加上解構函式來執行一下:
看到了吧,因為我們對同一塊記憶體進行了兩次析構,導致程式崩掉,而且,淺拷貝的另一個問題是我們在修改一個變數的時候,另一個變數會受到影響,這樣耦合性很大的程式我們還是能避免儘量避免的好。所以怎樣才能避免淺拷貝呢,就是使用深拷貝。我們為類實現自己的拷貝建構函式。
像這樣:
#include<stdio.h> class test { public: int num; int *point; test() {} test(test &tmp) { point = new int; *point = *tmp.point; } ~test() { delete point; } }; int main() { test t1; t1.point=new int; scanf("%d",&t1.num); test t2=t1; printf("%d %d %p %p\n",t1.num,t2.num,t1.point,t2.point); return 0; }
結果就是這樣:
深拷貝兩個指標使用了不同的記憶體。
但是深拷貝的程式碼中我為什麼沒有過載等號運算子呢?因為我不知道怎麼判斷一個類的指標成員變數是否申請了記憶體。他沒申請的話,因為還沒有發生複製,所以是野指標。申請了記憶體後,他便指向了那塊記憶體,但是我實在是想不出來怎麼判斷是否已經申請了記憶體,所以我沒有辦法寫過載等號函式。如果你找到了解決辦法的話,還請您能留個言或郵箱告訴我一下,感謝。