最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++超詳細(xì)講解析構(gòu)函數(shù)

 更新時(shí)間:2022年06月02日 08:36:40   作者:iheal  
既然在創(chuàng)建對象時(shí)有構(gòu)造函數(shù)(給成員初始化),那么在銷毀對象時(shí)應(yīng)該還有一個(gè)清除成員變量數(shù)據(jù)的操作咯,析構(gòu)函數(shù)與構(gòu)造函數(shù)功能相反,析構(gòu)函數(shù)不是完成對象的銷毀,局部對象銷毀工作是由編譯器完成的。而對象在銷毀時(shí)會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù),完成類的一些資源清理工作

特性

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

特征如下:

  • 析構(gòu)函數(shù)名是~類名;
  • 無參數(shù)無返回值;
  • 一個(gè)類有且只有一個(gè)析構(gòu)函數(shù);
  • 對象聲明周期結(jié)束,編譯器自動(dòng)調(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ù)
}

輸出:

析構(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;
}

輸出:

析構(gòu)函數(shù)在程序即將結(jié)束時(shí),調(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ù)會(huì)去只會(huì)處理自定義類型的成員變量,那么析構(gòu)既然和構(gòu)造相對應(yīng),析構(gòu)也應(yīng)該是只去處理自定義類型的成員變量吧,確實(shí)如此,析構(gòu)函數(shù)不會(huì)對內(nèi)置類型有任何處理,只會(huì)在調(diào)用自身的析構(gòu)后再去調(diào)用自定義類型成員的析構(gòu)。

關(guān)于編譯器自動(dòng)生成的析構(gòu)函數(shù),下面的程序我們會(huì)看到,編譯器生成的析構(gòu)函數(shù),會(huì)對自定類型成員調(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;
}

輸出:

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

  • 內(nèi)置類型不處理;
  • 自定義類型成員調(diào)用相應(yīng)的析構(gòu)函數(shù);

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

如果成員變量含有指針,并且指針指向一塊我們正使用的空間,指針也是內(nèi)置類型,那如果不釋放指針指向的那塊空間就會(huì)造成內(nèi)存泄漏,而編譯器生成的析構(gòu)函數(shù)是不會(huì)處理此情況的,因?yàn)樾枰覀冊谖鰳?gòu)函數(shù)中主動(dòng)釋放內(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ù)無論是我們顯式定義的還是編譯器生成的,都會(huì)在對象的聲明周期結(jié)束時(shí)自動(dòng)調(diào)用,并且會(huì)調(diào)用自定義類型成員變量的析構(gòu)函數(shù)來釋放資源,而對內(nèi)置類型不做處理。

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

  • 類的成員都是自定義類型的;
  • 類的成員都是非指針的內(nèi)置類型;
  • 成員有指針,但并沒有管理內(nèi)存資源;

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

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

到此這篇關(guān)于C++超詳細(xì)講解析構(gòu)函數(shù)的文章就介紹到這了,更多相關(guān)C++析構(gòu)函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c++之time_t和struct tm及時(shí)間戳的正確使用方式

    c++之time_t和struct tm及時(shí)間戳的正確使用方式

    C++中處理時(shí)間的常用數(shù)據(jù)類型有time_t和struct tm,time_t通常用來表示時(shí)間戳,即從1970年1月1日至今的秒數(shù),struct tm是一個(gè)結(jié)構(gòu)體,用來存儲(chǔ)年、月、日、時(shí)、分、秒等信息,時(shí)間戳可以通過gmtime()轉(zhuǎn)換為struct tm類型,反之亦然
    2024-10-10
  • C++中關(guān)于互斥量的全面認(rèn)知

    C++中關(guān)于互斥量的全面認(rèn)知

    線程的主要優(yōu)勢在于,能夠通過全局變量來共享信息。不過,這種便捷的共享是有代價(jià)的:必須確保多個(gè)線程不會(huì)同時(shí)修改同一變量,或者某一線程不會(huì)讀取正由其他線程修改的變量。為了防止出現(xiàn)線程某甲試圖訪?問一共享變量時(shí),線程某乙正在對其進(jìn)行修改。引入了互斥量
    2022-05-05
  • C++讀寫配置項(xiàng)的基本操作

    C++讀寫配置項(xiàng)的基本操作

    這篇文章主要介紹了C++讀寫配置項(xiàng)的基本操作,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下
    2021-01-01
  • c++ vector造成的內(nèi)存泄漏問題

    c++ vector造成的內(nèi)存泄漏問題

    這篇文章主要介紹了c++ vector造成的內(nèi)存泄漏問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C語言每日練習(xí)之字符串反轉(zhuǎn)

    C語言每日練習(xí)之字符串反轉(zhuǎn)

    這篇文章主要介紹了C語言字符串反轉(zhuǎn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-11-11
  • C++詳細(xì)分析線程間的同步通信

    C++詳細(xì)分析線程間的同步通信

    線程間不通信的話,每個(gè)線程受CPU的調(diào)度,沒有任何執(zhí)行上的順序可言,線程1和線程2是根據(jù)CPU調(diào)度算法來的,兩個(gè)線程都有可能先運(yùn)行,是不確定的,線程間的運(yùn)行順序是不確定的,所以多線程程序出問題,難以復(fù)現(xiàn),本章我們就來了解線程間的同步通信
    2022-05-05
  • C++ 中滾動(dòng)條的滾動(dòng)問題

    C++ 中滾動(dòng)條的滾動(dòng)問題

    本文主要通過一個(gè)示例,給大家介紹了C++中滾動(dòng)條的滾動(dòng)問題,以及相關(guān)參數(shù)的解釋,非常的詳細(xì),有需要的小伙伴可以參考下。
    2015-06-06
  • C語言轉(zhuǎn)義字符詳解

    C語言轉(zhuǎn)義字符詳解

    這篇文章主要介紹了C語言轉(zhuǎn)義字符詳解,本篇文章通過簡要的案例,講解了C語言轉(zhuǎn)義字符該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++ 將文件數(shù)據(jù)一次性加載進(jìn)內(nèi)存實(shí)例代碼

    C++ 將文件數(shù)據(jù)一次性加載進(jìn)內(nèi)存實(shí)例代碼

    這篇文章主要介紹了C++ 將文件數(shù)據(jù)一次性加載進(jìn)內(nèi)存實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C++如何切割String對象的方法

    C++如何切割String對象的方法

    C++相較于Java,Python 并沒有提供的字符串分割的函數(shù)split,因此需要自己進(jìn)行編寫,本文主要介紹了C++如何切割String對象的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05

最新評論

麻城市| 庆城县| 通榆县| 宁陵县| 鹿泉市| 黄山市| 四子王旗| 乐安县| 那坡县| 鹤峰县| 麻城市| 庐江县| 沧州市| 石泉县| 博爱县| 武城县| 濉溪县| 江达县| 淮南市| 凤庆县| 镇赉县| 潮安县| 济阳县| 阜城县| 德昌县| 乌拉特前旗| 辽阳县| 鹤峰县| 金沙县| 肥东县| 永德县| 高碑店市| 武城县| 临桂县| 碌曲县| 南靖县| 曲松县| 西安市| 遵化市| 高雄县| 晋州市|