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

詳解C++之類和對(duì)象(2)

 更新時(shí)間:2021年11月11日 08:35:37   作者:LUYAO_LY  
類是創(chuàng)建對(duì)象的模板,一個(gè)類可以創(chuàng)建多個(gè)對(duì)象,每個(gè)對(duì)象都是類類型的一個(gè)變量;創(chuàng)建對(duì)象的過(guò)程也叫類的實(shí)例化。每個(gè)對(duì)象都是類的一個(gè)具體實(shí)例(Instance),擁有類的成員變量和成員函數(shù)

一.構(gòu)造函數(shù)

1.構(gòu)造函數(shù)的定義:

構(gòu)造函數(shù) 是一個(gè) 特殊的成員函數(shù),名字與類名相同 , 創(chuàng)建類類型對(duì)象時(shí)由編譯器自動(dòng)調(diào)用 ,保證每個(gè)數(shù)據(jù)成員都有 一個(gè)合適的初始值,并且 在對(duì)象的生命周期內(nèi)只調(diào)用一次 。 其實(shí)構(gòu)造函數(shù)的作用就是完成成員變量的初始化 ,但不同于c語(yǔ)言的初始化構(gòu)造函數(shù)可以實(shí)在創(chuàng)造對(duì)象的同時(shí)就完成成員變量的初始化。

2.構(gòu)造函數(shù)的特征:

1. 函數(shù)名與類名相同。

2. 無(wú)返回值。

3. 對(duì)象實(shí)例化時(shí)編譯器 自動(dòng)調(diào)用 對(duì)應(yīng)的構(gòu)造函數(shù)。

4. 構(gòu)造函數(shù)可以重載。

3.構(gòu)造函數(shù)的實(shí)現(xiàn):

構(gòu)造函數(shù)的實(shí)現(xiàn)主要有三種,

1.當(dāng)用戶沒(méi)有實(shí)現(xiàn)構(gòu)造函數(shù)的話系統(tǒng)會(huì)默認(rèn)創(chuàng)造一個(gè),此時(shí)系統(tǒng)會(huì)將內(nèi)置類型的成員變量賦予隨機(jī)值,而對(duì)于自定義類型的成員變量則會(huì)調(diào)用他們的構(gòu)造函數(shù)。(注:內(nèi)置類型一般指的是:int char double float等這些定義好的類型,自定義類型指的是:struct這種類型以及class類這種)。

2.當(dāng)然用戶也可以自己實(shí)現(xiàn)構(gòu)造函數(shù),一種為無(wú)參構(gòu)造

3.類一種為帶參構(gòu)造,但是在帶參構(gòu)造中我們使用全缺省構(gòu)造。我們用代碼展示一下:

3.1.系統(tǒng)默認(rèn)的構(gòu)造函數(shù)

我們可以看到當(dāng)我們沒(méi)有在Data類進(jìn)行函數(shù)構(gòu)造的時(shí)系統(tǒng)將會(huì)自己默認(rèn)創(chuàng)建構(gòu)造函數(shù),對(duì)內(nèi)置類型變量賦予隨機(jī)值,自定義類型調(diào)用自己的構(gòu)造函數(shù)(若自定義類型也沒(méi)有定義構(gòu)造函數(shù)那么此例子中的_a1和_a2也會(huì)被賦予隨機(jī)值)

3.2無(wú)參構(gòu)造

3.3 帶參構(gòu)造

這里出一個(gè)問(wèn)題對(duì)于代碼風(fēng)格造成的問(wèn)題:成員變量year最后的結(jié)果是多少呢?

class A{public:A(int year){year = year;}private:int year;};int main(){A a(20);}

答案是:隨機(jī)值。那么為什么是隨機(jī)值呢?這里主要是變量之間它采用了就近原則,所以等式左邊的year會(huì)直接尋找離他最近的變量所以會(huì)將等式右邊的year直接賦值給它自己,所以year最后的值就是隨機(jī)值。

我們繼續(xù)來(lái)說(shuō)帶參的構(gòu)造函數(shù),我們一般推薦使用的是全缺省的構(gòu)造函數(shù)(注:

無(wú)參的構(gòu)造函數(shù)和全缺省的構(gòu)造函數(shù)都稱為默認(rèn)構(gòu)造函數(shù),并且默認(rèn)構(gòu)造函數(shù)只能有一個(gè)。無(wú)參構(gòu)造函數(shù)、全缺省構(gòu)造函數(shù)、我們沒(méi)寫(xiě)編譯器默認(rèn)生成的構(gòu)造函數(shù),三者都可以認(rèn)為是默認(rèn)成員函數(shù)。

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

構(gòu)造函數(shù)時(shí)完成對(duì)象的初始化,那么一個(gè)對(duì)象又是怎么樣被銷毀的呢?

1.析構(gòu)函數(shù)的定義

與構(gòu)造函數(shù)功能相反,析構(gòu)函數(shù)不是完成對(duì)象的銷毀,局部對(duì)象銷毀工作是由編譯器完成的。而 對(duì)象在銷毀時(shí)會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù),完成類的一些清理工作。

2.析構(gòu)函數(shù)的特征

1. 析構(gòu)函數(shù)名是在類名前加上字符 ~ 。

2. 無(wú)參數(shù)無(wú)返回值。

3. 一個(gè)類有且只有一個(gè)析構(gòu)函數(shù)。若未顯式定義,系統(tǒng)會(huì)自動(dòng)生成默認(rèn)的析構(gòu)函數(shù) 。

4. 對(duì)象生命周期結(jié)束時(shí), C++ 編譯系統(tǒng)系統(tǒng)自動(dòng)調(diào)用析構(gòu)函數(shù)。

這里我們用棧的例子來(lái)說(shuō)明析構(gòu)函數(shù)的實(shí)現(xiàn)以及作用。

class Stack
	{
	public:
		Stack(int capacity = 4)
		{
			_a = (int*)malloc(sizeof(int)*capacity);
			if (_a == nullptr)
			{
				cout << "malloc fail" << endl;
				exit(-1);
			}
			_top = 0;
			_capacity = capacity;
		}
	//析構(gòu)函數(shù)的實(shí)現(xiàn)
		~Stack()
		{
			// 像Stack這樣的類,對(duì)象中的資源需要清理工作,就用析構(gòu)函數(shù)
			free(_a);
			_a = nullptr;
			_top = _capacity = 0;
		}
 	private:
		int* _a;
		int _top;
		int _capacity;
	};

這里是完成構(gòu)造函數(shù),有自己定義的析構(gòu)函數(shù)的效果。同構(gòu)造函數(shù)一樣對(duì)于內(nèi)置成員變量析構(gòu)函數(shù)會(huì)置為隨機(jī)值,而自定義類型則會(huì)去調(diào)用他們的析構(gòu)函數(shù)。

三 拷貝函數(shù)

如果某些時(shí)候我們需要去復(fù)制一個(gè)對(duì)象,這樣的話我們?cè)撛趺礃尤ソ鉀Q呢?

這里我們就需要引入拷貝函數(shù)。那么什么叫做拷貝函數(shù)呢?我們應(yīng)該去怎么實(shí)現(xiàn)呢?有什么注意事項(xiàng)呢?這里我們一一來(lái)說(shuō)道。

1.拷貝函數(shù)定義

構(gòu)造函數(shù) : 只有單個(gè)形參 ,該形參是對(duì)本 類類型對(duì)象的引用 ( 一般常用 const 修飾 ) ,在用 已存在的類類型對(duì)象 創(chuàng)建新對(duì)象時(shí)由編譯器自動(dòng)調(diào)用 。

2.拷貝函數(shù)的特性

1. 拷貝構(gòu)造函數(shù) 是構(gòu)造函數(shù)的一個(gè)重載形式 。

2. 拷貝構(gòu)造函數(shù)的參數(shù)只有一個(gè)且必須使用引用傳參,使用傳值方式會(huì)引發(fā)無(wú)窮遞歸調(diào)用 。

3. 若未顯示定義,系統(tǒng)生成默認(rèn)的拷貝構(gòu)造函數(shù)。 默認(rèn)的拷貝構(gòu)造函數(shù)對(duì)象按內(nèi)存存儲(chǔ)按字節(jié)序完成拷 貝,這種拷貝我們叫做淺拷貝,或者值拷貝。

3.拷貝函數(shù)的實(shí)現(xiàn)

拷貝函數(shù)的實(shí)現(xiàn)分為兩種一種是系統(tǒng)默認(rèn),一種是自己定義。我們分別來(lái)看其效果

class A 
{
public:
	A() 
	{ 
         _a1 = 1;
		 _a2 = 2;
	}
	~A() 
	{
		cout << "A()" << endl;
	}
private:
	int _a1;
	int _a2;
};
 class Data
{
public:
	/*Data() 
	{
		_year = 2021;
		_month = 12;
		_day = 12;
	}*/
	//Data(int year, int month, int day) 
	//{
	//	_year = year;
	//	_month = month;
	//	_day = day;
	//}
	Data(int year = 2022, 
		int month = 12, 
		int day = 12) 
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
	A a;
};
 int main() 
{
	Data s;
	//拷貝函數(shù)的調(diào)用
	Data s2(s);
	return 0;
}

調(diào)用系統(tǒng)默認(rèn)生成拷貝函數(shù)(注:這里拷貝函數(shù)的拷貝對(duì)自定義類型和內(nèi)置類型的成員變量處理都是一致的完成字節(jié)序的值拷貝)

圖1 調(diào)用系統(tǒng)默認(rèn)生成的拷貝函數(shù)

圖2 調(diào)用用戶自己定義的拷貝函數(shù)

在這里我們順便說(shuō)一下在自定義拷貝函數(shù)的時(shí)候一定要使用引用不然會(huì)出現(xiàn)無(wú)限遞歸例如 Data(Data s){}正確的使用是Data (const Data & s){}其中const是為了保護(hù)原數(shù)據(jù)不被輕易改動(dòng)。

class A 
{
public:
	A() 
	{ 
         _a1 = 1;
		 _a2 = 2;
	}
	~A() 
	{
		cout << "A()" << endl;
	}
private:
	int _a1;
	int _a2;
};
 class Data
{
public:
	/*Data() 
	{
		_year = 2021;
		_month = 12;
		_day = 12;
	}*/
	//Data(int year, int month, int day) 
	//{
	//	_year = year;
	//	_month = month;
	//	_day = day;
	//}
	Data( const Data &s) 
	{
		_year = s._year;
		_month = s._month;
		_day = s._day;
 	}
	Data(int year = 2023, 
		int month = 12, 
		int day = 12) 
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
	A a;
};
 int main() 
{
	Data s;
	//拷貝函數(shù)的調(diào)用
	Data s2(s);
	return 0;
}

我們可以發(fā)現(xiàn)s2均完整的賦值了s的內(nèi)容,但是這里真的就沒(méi)有問(wèn)題了嗎?如果我們使用系統(tǒng)默認(rèn)生成的拷貝函數(shù)成員變量中含有指針那么會(huì)出現(xiàn)什么樣的問(wèn)題呢?

class String
{
public:
String(const char* str = "jack")
 {
_str = (char*)malloc(strlen(str) + 1);
strcpy(_str, str);
 }
~String()
 {
cout << "~String()" << endl;
free(_str);
 }
private:
char* _str;
};
int main()
{
String s;
String s1(s);
}

我們可以看到雖然雖然s1拷貝了s的內(nèi)容但是最后系統(tǒng)還是拋出了錯(cuò)誤那么這個(gè)錯(cuò)誤來(lái)自那里呢?

我們看這幅圖

這里就是我們之前說(shuō)的系統(tǒng)默認(rèn)生成的拷貝函數(shù)是淺拷貝,那么怎么去完成深拷貝我們后邊在繼續(xù)講解。

總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • C++創(chuàng)建多線程的方法總結(jié)

    C++創(chuàng)建多線程的方法總結(jié)

    下個(gè)迭代有個(gè)任務(wù)很有趣,用大量的線程去訪問(wèn)一個(gè)接口,直至其崩潰為止,這就需要多線程的知識(shí),這也不是什么難事,本文總結(jié)一下C++中的多線程方法std、boost、pthread、windows?api,感興趣的朋友可以參考下
    2024-01-01
  • C++中內(nèi)存池的簡(jiǎn)單原理及實(shí)現(xiàn)詳解

    C++中內(nèi)存池的簡(jiǎn)單原理及實(shí)現(xiàn)詳解

    內(nèi)存池的思想是,在真正使用內(nèi)存之前,預(yù)先申請(qǐng)分配一定數(shù)量、大小預(yù)設(shè)的內(nèi)存塊留作備用。本文主要來(lái)和大家聊聊內(nèi)存池的簡(jiǎn)單原理及實(shí)現(xiàn),希望對(duì)大家有所幫助
    2023-03-03
  • 深入解析C++編程中__alignof 與__uuidof運(yùn)算符的使用

    深入解析C++編程中__alignof 與__uuidof運(yùn)算符的使用

    這篇文章主要介紹了C++編程中__alignof 與__uuidof運(yùn)算符的使用,是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2016-01-01
  • C++中的多態(tài)與虛函數(shù)的內(nèi)部實(shí)現(xiàn)方法

    C++中的多態(tài)與虛函數(shù)的內(nèi)部實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇C++中的多態(tài)與虛函數(shù)的內(nèi)部實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • C++進(jìn)一步認(rèn)識(shí)類與對(duì)象

    C++進(jìn)一步認(rèn)識(shí)類與對(duì)象

    類是創(chuàng)建對(duì)象的模板,一個(gè)類可以創(chuàng)建多個(gè)對(duì)象,每個(gè)對(duì)象都是類類型的一個(gè)變量;創(chuàng)建對(duì)象的過(guò)程也叫類的實(shí)例化。每個(gè)對(duì)象都是類的一個(gè)具體實(shí)例(Instance),擁有類的成員變量和成員函數(shù)
    2021-10-10
  • vscode調(diào)試gstreamer源碼的詳細(xì)流程

    vscode調(diào)試gstreamer源碼的詳細(xì)流程

    在本文中主要介紹了如何使用vscode調(diào)試C++和python程序,并進(jìn)一步分析了如何調(diào)試gstreamer源碼,講述了如何調(diào)試gstreamer源碼的具體流程,感興趣的朋友跟隨小編一起看看吧
    2023-01-01
  • C/C++ 中堆和棧及靜態(tài)數(shù)據(jù)區(qū)詳解

    C/C++ 中堆和棧及靜態(tài)數(shù)據(jù)區(qū)詳解

    這篇文章主要介紹了C/C++ 中堆和棧及靜態(tài)數(shù)據(jù)區(qū)詳解的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • 關(guān)于vector的常見(jiàn)用法詳解

    關(guān)于vector的常見(jiàn)用法詳解

    這篇文章主要介紹了關(guān)于vector的常見(jiàn)用法詳解,vector本身可以作為數(shù)組使用,而且在一些元素個(gè)數(shù)不確定的場(chǎng)合可以很好地節(jié)省空間,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • C語(yǔ)言超詳細(xì)講解指針與結(jié)構(gòu)體

    C語(yǔ)言超詳細(xì)講解指針與結(jié)構(gòu)體

    指針提供了對(duì)地址操作的一種方法,因此,使用指針可使得C語(yǔ)言能夠更高效地實(shí)現(xiàn)對(duì)計(jì)算機(jī)底層硬件的操作。另外,通過(guò)指針可以更便捷地操作數(shù)組。C數(shù)組允許定義可存儲(chǔ)相同類型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是C編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許您存儲(chǔ)不同類型的數(shù)據(jù)項(xiàng)
    2022-05-05
  • 深入了解C語(yǔ)言棧的創(chuàng)建

    深入了解C語(yǔ)言棧的創(chuàng)建

    棧只允許在一端進(jìn)行插入或刪除操作的線性表。首先棧是一種線性表,但是限定這種線性表只能在某一端進(jìn)行插入和刪除操作,這篇文章主要介紹了C語(yǔ)言對(duì)棧的實(shí)現(xiàn)基本操作
    2021-07-07

最新評(píng)論