C++深淺複製構造函數

1、淺層複製構造函數(利用默認的複製構造函數)

如果對象A的數據成員中有指針,那麼當我們把對象A複製給對象B的時候,此時對象A和對象B中的指針數據成員都是指向同一塊內存區域的,當兩個對象中的任意一個對象被刪除的時候,指針數據成員的那塊內存區域也會被刪除,因此另一個對象的成員指針變成了野指針,程序也會因此而崩潰。

class MyClass
{
public:
	MyClass()
	{
		p = new int; 
		*p = 10;
	}
	~MyClass()
	{
		delete p;
		p = NULL;
	}
	void set(int i)
	{
		*p = i;
	}
	int *getAdress()
	{
		return p;
	}
private:
	int *p;
};
int main()
{
	//創建一個對象p
	MyClass *p = new MyClass;

	//調用默認的複製構造函數創建對象p1
	MyClass p1(*p);

	//兩個對象指針數據成員的地址是一樣的
	cout<<"對象p的數據成員地址:"<<p->getAdress()<<endl;
	cout<<"對象p1的數據成員地址:"<<p1.getAdress()<<endl;

	//對象p改變了數據成員的值,p1成員的值也會被改變
	p->set(999);

	//刪除對象p,同時p1的指針成員也被刪除掉了,因爲他們指向的是同一塊內存地址
	delete p;
	
	//程序結束時崩潰
	//因爲程序結束時會自動釋放p1,這時發現指針成員已經不存在了,做了一次重複的刪除,所以程序崩潰
	return 0;
}


2、深層複製構造函數(自定義複製構造函數)
解決上述問題,需要顯式定義一個複製構造函數,在複製構造函數中爲成員指針分配新的內存空間,然後將舊對象成員的數據賦值給新對象成員,兩個對象的數據成員各自擁有不同的內存區域,因此不會相互影響,這種方式就叫做深層複製。
class MyClass
{
public:
	MyClass()
	{
		p = new int; 
		*p = 10;
	}
	MyClass(const MyClass &m)
	{
		//申請一塊新的內存存放指針對象
		p = new int;
		*p = *(m.p);
	}
	~MyClass()
	{
		delete p;
		p = NULL;
	}
	void set(int i)
	{
		*p = i;
	}
	int *getAdress()
	{
		return p;
	}
private:
	int *p;
};
int main()
{
	//創建一個對象p
	MyClass *p = new MyClass;

	//調用默認的複製構造函數創建對象p1
	MyClass p1(*p);

	//兩個對象指針數據成員各自有用自己的內存區域
	cout<<"對象p的數據成員地址:"<<p->getAdress()<<endl;
	cout<<"對象p1的數據成員地址:"<<p1.getAdress()<<endl;

	//對象p改變了數據成員的值,不會影響p1
	p->set(999);

	//刪除p,不會影響p1
	delete p;
	
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章