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

C++修煉之構(gòu)造函數(shù)與析構(gòu)函數(shù)

 更新時(shí)間:2023年03月31日 14:33:22   作者:花想云  
本章節(jié)我們將學(xué)習(xí)類的6個(gè)默認(rèn)成員函數(shù)中的構(gòu)造函數(shù)與析構(gòu)函數(shù),并對(duì)比C語言階段的內(nèi)容來學(xué)習(xí)它們的各自的特性,感興趣的同學(xué)可以參考閱讀

??默認(rèn)成員函數(shù)

上一章中我們談到,如果一個(gè)類中什么成員也沒有,那么這個(gè)類就叫作空類。其實(shí)這么說是不太嚴(yán)謹(jǐn)?shù)?,因?yàn)?code>一個(gè)類不可能什么都沒有。

當(dāng)我們定義好一個(gè)類,不做任何處理時(shí),編譯器會(huì)自動(dòng)生成以下6個(gè)默認(rèn)成員函數(shù)

  • 默認(rèn)成員函數(shù):如果用戶沒有手動(dòng)實(shí)現(xiàn),則編譯器會(huì)自動(dòng)生成的成員函數(shù)

  • 構(gòu)造函數(shù):主要完成初始化工作;

  • 析構(gòu)函數(shù):主要完成清理工作;

  • 拷貝構(gòu)造:使用一個(gè)同類的對(duì)象初始化創(chuàng)建一個(gè)對(duì)象;

  • 賦值重載:把一個(gè)對(duì)象賦值給另一個(gè)對(duì)象;

  • 取地址重載普通對(duì)象取地址操作;

  • 取地址重載(const):const對(duì)象取地址操作;

本章我們將學(xué)習(xí)兩個(gè)默認(rèn)成員函數(shù)——構(gòu)造函數(shù)析構(gòu)函數(shù)。

??構(gòu)造函數(shù)

??引例

在C語言階段,我們實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)時(shí),有一件事很苦惱,就是每當(dāng)創(chuàng)建一個(gè)stack對(duì)象(之前叫作定義一個(gè)stack類型的變量)后,首先得調(diào)用它的專屬初始化函數(shù)StackInit來初始化對(duì)象。

typedef int dataOfStackType;

typedef struct stack
{
	dataOfStackType* a;
	int top;
	int capacity;
}stack;

void StackInit(stack* ps);
//...

 int main()
 {
	 stack s;
	 StackInit(&s);
	 //...
	 return 0;
 }

這不免讓人覺得有點(diǎn)麻煩。在C++中,構(gòu)造函數(shù)為我們很好的解決了這一問題。

??構(gòu)造函數(shù)的概念及特性

構(gòu)造函數(shù)是一個(gè)特殊的成員函數(shù)。構(gòu)造函數(shù)雖然叫作構(gòu)造,但是其主要作用并不是開辟空間創(chuàng)建對(duì)象,而是初始化對(duì)象

構(gòu)造函數(shù)之所以特殊,是因?yàn)橄啾扔谄渌蓡T函數(shù),它具有如下特性

  1. 函數(shù)名與類名相同;
  2. 無返回值
  3. 對(duì)象實(shí)例化時(shí),編譯器自動(dòng)調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù);
  4. 構(gòu)造函數(shù)可以重載;

??舉例??

class Date
{
public:
	//無參的構(gòu)造函數(shù)
	Date()
	{};
	//帶參的構(gòu)造函數(shù)
	Date(int year,int month,int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}

private:
	int _year;
	int _month;
	int _day;
};

void TestDate()
{
	Date d1;//調(diào)用無參構(gòu)造函數(shù)(自動(dòng)調(diào)用)
	Date d2(2023, 3, 29);//調(diào)用帶參構(gòu)造函數(shù)(自動(dòng)調(diào)用)
}

??特別注意??

  • 創(chuàng)建對(duì)象時(shí)編譯器會(huì)自動(dòng)調(diào)用構(gòu)造函數(shù),若是調(diào)用無參構(gòu)造函數(shù),則無需在對(duì)象后面使用()。否則會(huì)產(chǎn)生歧義:編譯器無法確定你是在聲明函數(shù)還是在創(chuàng)建對(duì)象。

??錯(cuò)誤示例??

//錯(cuò)位示例
Date d3();
  1. 如果類中沒有顯式定義構(gòu)造函數(shù),則C++編譯器會(huì)自動(dòng)生成一個(gè)無參的默認(rèn)構(gòu)造函數(shù),一旦用戶顯式定義編譯器將不再生成。
class Date
{
public:
	//若用戶沒有顯示定義,則編譯器自動(dòng)生成。
	/*Date(int year,int month,int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}*/

private:
	int _year;
	int _month;
	int _day;
};
  1. 默認(rèn)生成構(gòu)造函數(shù),對(duì)內(nèi)置類型成員不作處理;對(duì)自定義類型成員,會(huì)調(diào)用它的默認(rèn)構(gòu)造函數(shù);
  • C++把類型分成內(nèi)置類型(基本類型)和自定義類型。內(nèi)置類型就是語言提供的數(shù)據(jù)類型,如:int、char、double…,自定義類型就是我們使用class、struct、union等自己定義的類型。

??舉例??

??默認(rèn)構(gòu)造函數(shù)對(duì)內(nèi)置類型??

class Date
{
public:
	//此處不對(duì)構(gòu)造函數(shù)做顯示定義,測(cè)試默認(rèn)構(gòu)造函數(shù)
	/*Date()
	{}*/

	void print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};
void TestDate1()
{
	Date d1;
	d1.print();
}

  • 如圖所示,默認(rèn)構(gòu)造函數(shù)的確未對(duì)內(nèi)置類型做處理。

 ??默認(rèn)構(gòu)造函數(shù)對(duì)自定義類型??

class stack
{
public:
	//此處對(duì)stack構(gòu)造函數(shù)做顯示定義
	stack()
	{
		cout <<"stack()" << endl;
		_a = nullptr;
		_top = _capacity = 0;
	}
private:
	int* _a;
	int _top;
	int _capacity;
};
class queue
{
public:
	//此處不對(duì)queue構(gòu)造函數(shù)做顯示定義,測(cè)試默認(rèn)構(gòu)造函數(shù)
	/*queue()
	{}*/
private:
	//自定義類型成員
	stack _s;
};

void TestQueue()
{
	queue q;
}

  • 如圖所示,在創(chuàng)建queue對(duì)象時(shí),默認(rèn)構(gòu)造函數(shù)對(duì)自定義成員_s做了處理,調(diào)用了它的默認(rèn)構(gòu)造函數(shù)stack()。

 這一波蜜汁操作讓很多C++使用者感到困惑與不滿,為什么要針對(duì)內(nèi)置類型和自定義類型做不同的處理呢?終于,在C++11中針對(duì)內(nèi)置類型成員不初始化的缺陷,又打了補(bǔ)丁,即:

  1. 內(nèi)置類型成員變量在類中聲明時(shí)可以給默認(rèn)值

??舉例??

class Date
{
public:
//...
	void print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	//使用默認(rèn)值
	int _year = 0;
	int _month = 0;
	int _day = 0;
};
void TestDate2()
{
	Date d2;
	d2.print();
}

  • 默認(rèn)值:若不對(duì)成員變量做處理,則使用默認(rèn)值。
  1. 無參的構(gòu)造函數(shù)和全缺省的構(gòu)造函數(shù)都稱為默認(rèn)構(gòu)造函數(shù),并且默認(rèn)構(gòu)造函數(shù)只能有一個(gè);

??舉例??

class Date
{
public:
	//無參的默認(rèn)構(gòu)造函數(shù)
	//Date()
	//{

	//}

	//全缺省的默認(rèn)構(gòu)造函數(shù)
	Date(int year = 0, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	int _year = 0;
	int _month = 0;
	int _day = 0;
};

??析構(gòu)函數(shù)

析構(gòu)函數(shù)構(gòu)造函數(shù)的特性相似,但功能有恰好相反。構(gòu)造函數(shù)是用來初始化對(duì)象的,析構(gòu)函數(shù)是用來銷毀對(duì)象的。

  • 需要注意的是,析構(gòu)函數(shù)并不是對(duì)對(duì)象本身進(jìn)行銷毀(因?yàn)榫植繉?duì)象出了作用域會(huì)自行銷毀,由編譯器來完成),而是在對(duì)象銷毀時(shí)會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù),對(duì)對(duì)象內(nèi)部的資源做清理(例如stack _s中的int* a)。

同樣,有了析構(gòu)函數(shù),我們?cè)僖膊挥脫?dān)心創(chuàng)建對(duì)象(或定義變量)后由于忘記釋放內(nèi)存而造成內(nèi)存泄漏了。

??舉例??

class Stack
{
public:
	Stack()
	{
		//...
	}
	void Push(int x)
	{
		//...

	}
	bool Empty()
	{
		// ...

	}
	int Top()
	{
		//...
	}
	void Destory()
	{
		//...
	}
private:
	// 成員變量
	int* _a;
	int _top;
	int _capacity;
};

void TestStack()
{
	Stack s;
	st.Push(1);
	st.Push(2);
	//過去需要手動(dòng)釋放
	st.Destroy();
}

??析構(gòu)函數(shù)的特性

  1. 析構(gòu)函數(shù)名是在類名前加上字符 ~
  2. 無參數(shù);
  3. 無返回值
  4. 一個(gè)類只能有一個(gè)析構(gòu)函數(shù)。若未顯式定義,系統(tǒng)會(huì)自動(dòng)生成默認(rèn)的析構(gòu)函數(shù);
  5. 析構(gòu)函數(shù)不能重載

??舉例??

class Date
{
public:
	Date()
	{
		cout << "Date()" << endl;
	}
	~Date()
	{
		cout << "~Date()" << endl;
	}
private:
	int _year = 0;
	int _month = 0;
	int _day = 0;
};
void TestDate3()
{
	Date d3;
	//d3生命周期結(jié)束時(shí)自動(dòng)調(diào)用構(gòu)造函數(shù)
}

為便于觀察,我們可以在析構(gòu)函數(shù)內(nèi)部寫點(diǎn)兒東西。

  1. 編譯器生成的默認(rèn)析構(gòu)函數(shù),對(duì)自定類型成員調(diào)用它的析構(gòu)函數(shù);

??舉例??

class stack
{
public:
	//此處對(duì)stack構(gòu)造函數(shù)做顯示定義
	stack()
	{
		cout <<"stack()" << endl;
		_a = nullptr;
		_top = _capacity = 0;
	}
	~stack()
	{
		cout << "~Stack()" << endl;
		free(_a);
		_a = nullptr;
		_top = _capacity = 0;
	}
private:
	int* _a;
	int _top;
	int _capacity;
};
class queue
{
public:
	//此處不對(duì)queue構(gòu)造函數(shù)做顯示定義,測(cè)試默認(rèn)構(gòu)造函數(shù)
	/*queue()
	{}*/
private:
	//自定義類型成員
	stack _s;
};

void TestQueue1()
{
	queue q;
}

  • 這里可能有小伙伴會(huì)好奇:為什么析構(gòu)函數(shù)不像構(gòu)造函數(shù)那樣區(qū)分內(nèi)置類型與自定義類型呢
    答案是:因?yàn)閮?nèi)置類型壓根不需要我們擔(dān)心清理工作,在其生命周期結(jié)束時(shí)會(huì)自動(dòng)銷毀。而自定義類型需要擔(dān)心,因?yàn)樽远x類型里可能含有申請(qǐng)資源(例如:malloc申請(qǐng)內(nèi)存須手動(dòng)釋放)。
  1. 如果類中沒有申請(qǐng)資源時(shí),析構(gòu)函數(shù)可以不寫,直接使用編譯器生成的默認(rèn)析構(gòu)函數(shù),比如Date類;有資源申請(qǐng)時(shí),一定要寫,否則會(huì)造成資源泄漏,比如stack。

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

相關(guān)文章

  • C++枚舉類型用法總結(jié)(枚舉字符常量代替常量)

    C++枚舉類型用法總結(jié)(枚舉字符常量代替常量)

    這篇文章主要介紹了C++枚舉類型用法總結(jié)(枚舉字符常量代替常量),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 利用Matlab實(shí)現(xiàn)圖像亮度分布統(tǒng)計(jì)圖

    利用Matlab實(shí)現(xiàn)圖像亮度分布統(tǒng)計(jì)圖

    這篇文章主要介紹了如何利用Matlab實(shí)現(xiàn)圖像亮度分布統(tǒng)計(jì)圖的繪制,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Matlab有一定的幫助,感興趣的可以了解一下
    2022-05-05
  • C++ STL array容器訪問元素的幾種方式

    C++ STL array容器訪問元素的幾種方式

    這篇文章主要介紹了C++ STL array容器訪問元素的幾種方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 實(shí)例分享cmake編譯一個(gè)簡(jiǎn)單c++項(xiàng)目(demo)

    實(shí)例分享cmake編譯一個(gè)簡(jiǎn)單c++項(xiàng)目(demo)

    下面通過一個(gè)小例子來說明cmake編譯一個(gè)c++項(xiàng)目,生成可執(zhí)行文件,需要的朋友可以參考下
    2020-02-02
  • C語言文件操作總結(jié)

    C語言文件操作總結(jié)

    本篇文章給大家通過代碼示例講述了C語言文件操作的相關(guān)知識(shí)點(diǎn),對(duì)此有興趣的朋友可以參考學(xué)習(xí)下。
    2018-03-03
  • C語言安全編碼數(shù)組記法的一致性

    C語言安全編碼數(shù)組記法的一致性

    這篇文章主要介紹了C語言安全編碼數(shù)組記法的一致性,需要的朋友可以參考下
    2014-07-07
  • C/C++實(shí)現(xiàn)獲取系統(tǒng)時(shí)間的示例代碼

    C/C++實(shí)現(xiàn)獲取系統(tǒng)時(shí)間的示例代碼

    C 標(biāo)準(zhǔn)庫(kù)提供了 time() 函數(shù)與 localtime() 函數(shù)可以獲取到當(dāng)前系統(tǒng)的日歷時(shí)間。本文將通過一些簡(jiǎn)單的示例為大家講講C++獲取系統(tǒng)時(shí)間的具體方法,需要的可以參考一下
    2022-12-12
  • c語言實(shí)現(xiàn)計(jì)算圓周率的近似值

    c語言實(shí)現(xiàn)計(jì)算圓周率的近似值

    這篇文章主要介紹了c語言實(shí)現(xiàn)計(jì)算圓周率的近似值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • C++ LeetCode1775通過最少操作次數(shù)使數(shù)組和相等

    C++ LeetCode1775通過最少操作次數(shù)使數(shù)組和相等

    這篇文章主要為大家介紹了C++ LeetCode1775通過最少操作次數(shù)使數(shù)組和相等,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • 詳解C++數(shù)組和數(shù)組名問題(指針、解引用)

    詳解C++數(shù)組和數(shù)組名問題(指針、解引用)

    這篇文章主要介紹了詳解C++數(shù)組和數(shù)組名問題(指針、解引用),指針的實(shí)質(zhì)就是個(gè)變量,它跟普通變量沒有任何本質(zhì)區(qū)別,指針本身是一個(gè)對(duì)象,同時(shí)指針無需在定義的時(shí)候賦值,具體內(nèi)容詳情跟隨小編一起看看吧
    2021-09-09

最新評(píng)論

法库县| 托里县| 迭部县| 澄迈县| 堆龙德庆县| 嘉义市| 逊克县| 桦川县| 石家庄市| 湘潭县| 揭阳市| 雷山县| 正定县| 南木林县| 万全县| 通城县| 罗平县| 枣强县| 繁峙县| 乌兰察布市| 宜昌市| 开鲁县| 库伦旗| 稻城县| 丹巴县| 屏东县| 葵青区| 黔江区| 绥中县| 湖州市| 辽中县| 高要市| 南汇区| 永济市| 华阴市| 安福县| 灵台县| 彭泽县| 丰镇市| 胶州市| 祥云县|