欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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ù),并對比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í),編譯器會自動(dòng)生成以下6個(gè)默認(rèn)成員函數(shù)

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

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

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

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

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

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

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

本章我們將學(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對象(之前叫作定義一個(gè)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;
 }

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

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

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

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

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

??特別注意??

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

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

//錯(cuò)位示例
Date d3();
  1. 如果類中沒有顯式定義構(gòu)造函數(shù),則C++編譯器會自動(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ù),對內(nèi)置類型成員不作處理;對自定義類型成員,會調(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ù)對內(nèi)置類型??

class Date
{
public:
	//此處不對構(gòu)造函數(shù)做顯示定義,測試默認(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ù)的確未對內(nèi)置類型做處理。

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

void TestQueue()
{
	queue q;
}

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

 這一波蜜汁操作讓很多C++使用者感到困惑與不滿,為什么要針對內(nèi)置類型和自定義類型做不同的處理呢?終于,在C++11中針對內(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)值:若不對成員變量做處理,則使用默認(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ù)是用來初始化對象的,析構(gòu)函數(shù)是用來銷毀對象的。

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

同樣,有了析構(gòu)函數(shù),我們再也不用擔(dān)心創(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);
	//過去需要手動(dòng)釋放
	st.Destroy();
}

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

  1. 析構(gòu)函數(shù)名是在類名前加上字符 ~;
  2. 無參數(shù);
  3. 無返回值
  4. 一個(gè)類只能有一個(gè)析構(gòu)函數(shù)。若未顯式定義,系統(tǒng)會自動(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ù),對自定類型成員調(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ù)做顯示定義,測試默認(rèn)構(gòu)造函數(shù)
	/*queue()
	{}*/
private:
	//自定義類型成員
	stack _s;
};

void TestQueue1()
{
	queue q;
}

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

    C語言?智能指針?shared_ptr?和?weak_ptr

    這篇文章主要介紹了C語言?智能指針?shared_ptr?和?weak_ptr,weak_ptr引入可以解決shared_ptr交叉引用時(shí)無法釋放資源的問題,下面來學(xué)習(xí)具體相關(guān)內(nèi)容吧,需要的朋友可以參考一下
    2022-04-04
  • 使用C語言實(shí)現(xiàn)繪制立體分離式環(huán)圖

    使用C語言實(shí)現(xiàn)繪制立體分離式環(huán)圖

    這篇文章主要為大家詳細(xì)介紹了使用C語言實(shí)現(xiàn)繪制立體分離式環(huán)圖的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • C++實(shí)現(xiàn)LeetCode(161.一個(gè)編輯距離)

    C++實(shí)現(xiàn)LeetCode(161.一個(gè)編輯距離)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(161.一個(gè)編輯距離),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C/C++中的內(nèi)存管理小結(jié)

    C/C++中的內(nèi)存管理小結(jié)

    這篇文章主要介紹了C/C++中的內(nèi)存管理小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • C語言實(shí)現(xiàn)煙花表白程序代碼

    C語言實(shí)現(xiàn)煙花表白程序代碼

    大家好,本篇文章主要講的是C語言實(shí)現(xiàn)煙花表白程序代碼,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • C++ 格式化日志輸出實(shí)現(xiàn)代碼

    C++ 格式化日志輸出實(shí)現(xiàn)代碼

    這篇文章主要介紹了C++ 格式化日志輸出實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2019-04-04
  • C++設(shè)計(jì)模式之外觀模式

    C++設(shè)計(jì)模式之外觀模式

    這篇文章主要介紹了C++設(shè)計(jì)模式之外觀模式,本文詳細(xì)講解了C++中的Facade模式,并給出了實(shí)例代碼,需要的朋友可以參考下
    2014-10-10
  • C語言詳解關(guān)鍵字sizeof與unsigned及signed的用法

    C語言詳解關(guān)鍵字sizeof與unsigned及signed的用法

    這篇文章主要為大家詳細(xì)介紹了C語言關(guān)鍵字sizeof&&unsigned&&signed,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • c++ 編程 幾個(gè)有用的宏詳解

    c++ 編程 幾個(gè)有用的宏詳解

    下面小編就為大家?guī)硪黄猚++ 編程 幾個(gè)有用的宏詳解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12
  • C++通過CryptoPP計(jì)算Hash值的過程詳解

    C++通過CryptoPP計(jì)算Hash值的過程詳解

    Crypto++ (CryptoPP) 是一個(gè)用于密碼學(xué)和加密的C++庫,它是一個(gè)開源項(xiàng)目,提供了大量的密碼學(xué)算法和功能,本文小編給大家介紹了C++通過CryptoPP計(jì)算Hash值的過程,文中通過代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11

最新評論