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

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

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

??默認成員函數(shù)

上一章中我們談到,如果一個類中什么成員也沒有,那么這個類就叫作空類。其實這么說是不太嚴謹?shù)模驗?code>一個類不可能什么都沒有。

當我們定義好一個類,不做任何處理時,編譯器會自動生成以下6個默認成員函數(shù)

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

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

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

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

  • 賦值重載:把一個對象賦值給另一個對象;

  • 取地址重載普通對象取地址操作;

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

本章我們將學習兩個默認成員函數(shù)——構(gòu)造函數(shù)析構(gòu)函數(shù)。

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

??引例

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

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;
 }

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

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

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

構(gòu)造函數(shù)之所以特殊,是因為相比于其它成員函數(shù),它具有如下特性

  1. 函數(shù)名與類名相同;
  2. 無返回值;
  3. 對象實例化時,編譯器自動調(diào)用對應(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ù)(自動調(diào)用)
	Date d2(2023, 3, 29);//調(diào)用帶參構(gòu)造函數(shù)(自動調(diào)用)
}

??特別注意??

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

??錯誤示例??

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

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

??舉例??

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

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

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

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

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

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

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

void TestQueue()
{
	queue q;
}

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

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

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

??舉例??

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

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

??舉例??

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

	//}

	//全缺省的默認構(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ù)是用來初始化對象的,析構(gòu)函數(shù)是用來銷毀對象的。

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

同樣,有了析構(gòu)函數(shù),我們再也不用擔心創(chuàng)建對象(或定義變量)后由于忘記釋放內(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);
	//過去需要手動釋放
	st.Destroy();
}

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

  1. 析構(gòu)函數(shù)名是在類名前加上字符 ~;
  2. 無參數(shù);
  3. 無返回值
  4. 一個類只能有一個析構(gòu)函數(shù)。若未顯式定義,系統(tǒng)會自動生成默認的析構(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é)束時自動調(diào)用構(gòu)造函數(shù)
}

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

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

??舉例??

class stack
{
public:
	//此處對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:
	//此處不對queue構(gòu)造函數(shù)做顯示定義,測試默認構(gòu)造函數(shù)
	/*queue()
	{}*/
private:
	//自定義類型成員
	stack _s;
};

void TestQueue1()
{
	queue q;
}

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

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

相關(guān)文章

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

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

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

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

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

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

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

    實例分享cmake編譯一個簡單c++項目(demo)

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評論

谢通门县| 肃北| 沭阳县| 吉木乃县| 利川市| 财经| 翼城县| 安吉县| 通河县| 察雅县| 石嘴山市| 日照市| 阿克苏市| 安远县| 永修县| 陈巴尔虎旗| 简阳市| 潢川县| 聂拉木县| 诸暨市| 连江县| 同仁县| 宜黄县| 东莞市| 开原市| 嘉义县| 镇平县| 达拉特旗| 哈密市| 平南县| 扎囊县| 喀什市| 子洲县| 抚州市| 绥江县| 太仆寺旗| 石渠县| 古交市| 绥中县| 九台市| 宿松县|