溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C++析構(gòu)函數(shù)怎么使用

發(fā)布時間:2022-06-02 10:52:28 來源:億速云 閱讀:161 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹了C++析構(gòu)函數(shù)怎么使用的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇C++析構(gòu)函數(shù)怎么使用文章都會有所收獲,下面我們一起來看看吧。

特性

析構(gòu)函數(shù)是特殊的成員函數(shù)

特征如下:

  • 析構(gòu)函數(shù)名是~類名;

  • 無參數(shù)無返回值;

  • 一個類有且只有一個析構(gòu)函數(shù);

  • 對象聲明周期結(jié)束,編譯器自動調(diào)用析構(gòu)函數(shù);

class Stack
{
public:
	Stack(int capacity = 4)
		:
		_size(0),
		_capacity(capacity),
		_p(new int[_capacity])
	{
		cout << "Stack(int capacity = 4)" << endl;
	}
	~Stack()
	{
		cout << "~Stack()" << endl;
		if (_p)
		{
			delete[](_p);
            _p = nullptr;
		}
		_size = _capacity = 0;
	}
private:	
	int _capacity;
	int _size;
	int* _p;
};
int main()
{
	Stack s;
	return 0;//程序結(jié)束,調(diào)用s的析構(gòu)函數(shù)
}

輸出:

C++析構(gòu)函數(shù)怎么使用

析構(gòu)函數(shù)處理自定義類型

class String
{
public:
	String(const char* str = "songxin")
	{
		cout << "String(const char* str = \"songxin\")" << endl;
		_str = (char*)malloc(strlen(str) + 1);
		strcpy(_str, str);
	}
	~String()
	{
		cout << "~String()" << endl;
		free(_str);
		_str = nullptr;
	}
private:
	char* _str;
};
class Person
{
public:
	Person()
		:
		_age(20),
		_name()
	{
		cout << "Person()" << endl;
	}
	~Person()
	{
		cout << "~Person()" << endl;
	}
private:
	String _name;
	int _age;
};
int main()
{
	Person p;
	return 0;
}

輸出:

C++析構(gòu)函數(shù)怎么使用

析構(gòu)函數(shù)在程序即將結(jié)束時,調(diào)用了Person的析構(gòu)函數(shù),在Person類的析構(gòu)函數(shù)即將結(jié)束接著調(diào)用String類的析構(gòu)函數(shù)。

歸納一下:

析構(gòu)函數(shù)是與構(gòu)造函數(shù)執(zhí)行相反的操作的,構(gòu)造函數(shù)負(fù)責(zé)給對象成員變量初始化并加載資源,而析構(gòu)函數(shù)則是給對象的成員變量清理資源,而不是清理對象本身。

編譯器生成的默認(rèn)析構(gòu)函數(shù)

編譯器默認(rèn)生成的析構(gòu)函數(shù)能做些什么工作呢?我們前面已經(jīng)介紹了編譯器生成的構(gòu)造函數(shù)會去只會處理自定義類型的成員變量,那么析構(gòu)既然和構(gòu)造相對應(yīng),析構(gòu)也應(yīng)該是只去處理自定義類型的成員變量吧,確實如此,析構(gòu)函數(shù)不會對內(nèi)置類型有任何處理,只會在調(diào)用自身的析構(gòu)后再去調(diào)用自定義類型成員的析構(gòu)。

關(guān)于編譯器自動生成的析構(gòu)函數(shù),下面的程序我們會看到,編譯器生成的析構(gòu)函數(shù),會對自定類型成員調(diào)用它的析構(gòu)函數(shù)。

class String
{
public:
	String(const char* str = "songxin")
	{
		cout << "String(const char* str = \"songxin\")" << endl;
		_str = (char*)malloc(strlen(str) + 1);
		strcpy(_str, str);
	}
	~String()
	{
		cout << "~String()" << endl;
		free(_str);
		_str = nullptr;
	}
private:
	char* _str;
};
class Person
{
public:
	Person()
		:
		_age(20),
		_name()
	{
		cout << "Person()" << endl;
	}
	
private:
	String _name;
	int _age;
};
int main()
{
	Person p;
	return 0;
}

輸出:

C++析構(gòu)函數(shù)怎么使用

默認(rèn)生成的析構(gòu)函數(shù)對成員變量的處理

  • 內(nèi)置類型不處理;

  • 自定義類型成員調(diào)用相應(yīng)的析構(gòu)函數(shù);

那成員變量中的內(nèi)置類型處不處理其實都無所謂嘛,反正都要歸還給操作系統(tǒng),但是有例外:

C++析構(gòu)函數(shù)怎么使用

如果成員變量含有指針,并且指針指向一塊我們正使用的空間,指針也是內(nèi)置類型,那如果不釋放指針指向的那塊空間就會造成內(nèi)存泄漏,而編譯器生成的析構(gòu)函數(shù)是不會處理此情況的,因為需要我們在析構(gòu)函數(shù)中主動釋放內(nèi)存,也就是說需要我們顯式的去定義析構(gòu)函數(shù)。

class Stack
{
public:
	Stack(int capacity = 4)
		:
		_size(0),
		_capacity(capacity),
		_p(new int[_capacity])//使用new去申請內(nèi)存
	{
		cout << "Stack(int capacity = 4)" << endl;
	}
	~Stack()
	{
		cout << "~Stack()" << endl;
		if (_p)
		{
			delete[](_p);//釋放內(nèi)存
            _p = nullptr;
		}
		_size = _capacity = 0;
	}
private:	
	int _capacity;
	int _size;
	int* _p;
};
int main()
{
	Stack s;
	return 0;//程序結(jié)束,調(diào)用s的析構(gòu)函數(shù)
}

析構(gòu)函數(shù)無論是我們顯式定義的還是編譯器生成的,都會在對象的聲明周期結(jié)束時自動調(diào)用,并且會調(diào)用自定義類型成員變量的析構(gòu)函數(shù)來釋放資源,而對內(nèi)置類型不做處理。

可以不顯式定義析構(gòu)函數(shù)的情況

  • 類的成員都是自定義類型的;

  • 類的成員都是非指針的內(nèi)置類型;

  • 成員有指針,但并沒有管理內(nèi)存資源;

如果類的成員變量有指針類型,并且我們讓指針指向了一塊動態(tài)分配的空間,那么就需要我們自己寫析構(gòu)函數(shù)了。

總結(jié):不是類直接管理另一塊內(nèi)存資源的,就不需要寫析構(gòu)函數(shù),編譯器自己生成的就能處理。

關(guān)于“C++析構(gòu)函數(shù)怎么使用”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“C++析構(gòu)函數(shù)怎么使用”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI