1. 程式人生 > >淺拷貝與深拷貝之間的區別

淺拷貝與深拷貝之間的區別

淺拷貝就是在類是以複製方式建立物件的時候,或者在變數進行復制的時候,沒有設定自定義的拷貝建構函式或過載等號運算子的拷貝函式,導致對變數中的所有進行拷貝,包括指標,即指標只拷貝地址,不會再為指標變數申請記憶體。

程式碼如下:

#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;
}

結果就是這樣:

深拷貝兩個指標使用了不同的記憶體。

但是深拷貝的程式碼中我為什麼沒有過載等號運算子呢?因為我不知道怎麼判斷一個類的指標成員變數是否申請了記憶體。他沒申請的話,因為還沒有發生複製,所以是野指標。申請了記憶體後,他便指向了那塊記憶體,但是我實在是想不出來怎麼判斷是否已經申請了記憶體,所以我沒有辦法寫過載等號函式。如果你找到了解決辦法的話,還請您能留個言或郵箱告訴我一下,感謝。