C++拷貝控制含有指針成員的類

當定義一個類時,我們顯式地或隱式地指定了此類型的對象在拷貝、賦值和銷燬時做什麼。一個類通過定義五種種特殊的成員函數來控制這些操作:拷貝構造函數、拷貝賦值運算符、移動構造函數、移動賦值運算符和析構函數。


在一個類中,如果類 沒有指針成員,一切方便,因爲默認合成的析構函數會自動處理所有的內存。但是如果一個類帶了指針成員,那麼需要我們自己來寫 析構函數來管理內存。


對於含有指針成員的類的對象調用默認拷貝構造函數、拷貝賦值運算符時,指針成員進行是淺拷貝,兩個對象的指針成員所指內存相同,這就導致指針被分配一次內存,但是程序結束時該內存卻被析構了兩次,第一次析構後,指針變爲野指針 ,第二次析構導致錯誤。
 

淺拷貝與深拷貝:
(1)淺拷貝只是複製了對象的引用地址,兩個對象指向同一個內存地址,所以修改其中任意的值,另一個值都會隨之變化,這就是淺拷貝;
(2)深拷貝是將對象及值複製過來,兩個對象修改其中任意的值另一個值不會改變,這就是深拷貝;

野指針與空指針:
(1)野指針:不是NULL指針,是指向"垃圾"內存(不可用內存)的指針,野指針是非常危險的。指針變量沒有被初始化,它缺省值是隨機的,它會亂指一氣;指針p被free或者delete之後,只是把指針所指的內存釋放掉了,沒有改變指針的值,此時,p淪落爲野指針。
(2)空指針:沒有存儲任何內存地址的指針就稱爲空指針(NULL指針)

總結:
(1)如果一個類帶了指針成員,它也需要自定義析構函數。
(2)如果一個類需要自定義析構函數,幾乎可以肯定它也需要自定義拷貝賦值運算符和拷貝構造函數。
(3)如果一個類需要一個拷貝構造函數,幾乎可以肯定它也需要一個拷貝賦值運算符。反之亦然,如果一個類需要一個拷貝賦值運算符,幾乎可以肯定它也需要一個拷貝構造函數。
 

demo:

#include "iostream"

using namespace std;

class Human
{
public:
	Human()
	{
		name = new char[4];
		string a = "123";
		strcpy_s(name, 4, a.c_str());

		cout << "Human Construct be called Successful!" << endl;
	}

#if 1
	Human(Human &hm)
	{
	   if (NULL != hm.name)
	   {
			name = new char[4];
			strcpy_s(name, 4, hm.name);
	   }

		cout << "Human copy Construct be called Successful!" << endl;
	}

	Human& operator=(const Human& hm)
	{
		if (this != &hm)
		{
			// 避免內存泄露
			if (name != NULL)
			{
				delete name;
				name = NULL;
			}

			if (NULL != hm.name)
			{
				name = new char[4];
				strcpy_s(name, 4, hm.name);
			}
		}

		cout << "Human operator be called Successful!" << endl;

		return *this;
	}
#endif

	~Human()
	{
		delete[] name;  //不需要判斷是否爲空
		cout << "Human Deconstrute be called Successful!" << endl;
	}

	int init()
	{
		return 0;
	}

	int age;
	char *name;
};


int main()
{
	{
		Human  hm1, hm3;  //調用構造函數

		Human hm2 = hm1;  //調用拷貝構造函數
		hm3 = hm1;        //調用拷貝賦值運算符
	}

	system("pause");
	return 0;
}

參考:

https://blog.csdn.net/caoshangpa/article/details/79226270
https://blog.csdn.net/fanx021/article/details/80207692
https://blog.csdn.net/liitdar/article/details/80656156
https://www.cnblogs.com/zpcdbky/p/5027481.html
https://www.cnblogs.com/codingmengmeng/p/9110608.html

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