国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值)

這篇具有很好參考價值的文章主要介紹了【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值),C++,c++,開發(fā)語言

??個人主頁:Forcible Bug Maker

??專欄:C++

目錄

前言

取地址及const取地址操作符重載

再談構造函數(shù)

初始化列表

隱式類型轉(zhuǎn)換

explicit關鍵字

成員變量缺省值

結語


前言

本篇主要內(nèi)容:類的六個默認成員函數(shù)中的取地址const取地址重載,構造函數(shù)初始化列表,隱式類型轉(zhuǎn)換缺省值。

上篇博客用之前學過的知識實現(xiàn)了一個簡單的日期類Date,在日期類中,有介紹到多種類型運算符重載的運用,如前置++后置++等。在運算符重載的過程中,有效的代碼復用也非常重要,可以大大簡化代碼編寫過程。最后還提到了const成員和友元。本篇博客將會介紹最后兩個類的默認成員函數(shù),不過并不困難。而文中再次談到的構造函數(shù)需要靜下心來理解。

取地址及const取地址操作符重載

【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值),C++,c++,開發(fā)語言

這兩個默認成員函數(shù)一般不用重新定義,編譯器默認生成的就夠用。

class Date
{
public:
	Date(int year = 2000, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
    // 取地址重載
	Date* operator&()
	{
		return this;
	}
    // const取地址重載
	const Date* operator&()const
	{
		return this;
	}
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
};

int main()
{
	Date d1;
	const Date d2;
	cout << &d1 << endl;
	cout << &d2 << endl;
	return 0;
}

【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值),C++,c++,開發(fā)語言

取地址重載,其實就是返回地址的兩個函數(shù),C++提供這種默認成員函數(shù)主要是想兼容操作符重載,給予C++更大的靈活性。在上面的代碼案例中,d1取地址時調(diào)用的是非const類型的取地址重載函數(shù),而d2取地址時調(diào)用的是const類型的取地址重載函數(shù)。我們可以改變返回值再去觀察一下。

【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值),C++,c++,開發(fā)語言

這次我們調(diào)整返回值后再打印,是否能感受到關于取地址重載的運用呢?其實,取地址重載很少用,除非你要惡作劇或者想讓別人獲取到指定的內(nèi)容,否則默認生成的取地址就是完全夠用的。

再談構造函數(shù)

初始化列表

C++的初始化列表(Initializer List)是構造函數(shù)的一種特性,用于初始化類的數(shù)據(jù)成員。在構造函數(shù)體執(zhí)行之前,初始化列表會先執(zhí)行,確保數(shù)據(jù)成員在構造函數(shù)體開始執(zhí)行之前就已經(jīng)被正確地初始化

初始化列表的使用:以一個冒號開始,接著是一個以逗號分隔的數(shù)據(jù)成員列表,每個“成員變量”后面跟一個放在括號中的初始值或表達式

class Date
{
public:
	Date(int year, int month, int day)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};

當使用上述類初始化對象時,三個成員函數(shù)都會成功在初始化列表中被傳入的參數(shù)初始化。你可能會問,為什么要有初始化列表,在構造函數(shù)的函數(shù)體中初始化不是很香嗎?可以來看看下面這個例子:

class stack
{
public:
	stack(int capacity = 4)
	{
		_a = (int*)malloc(sizeof(int) * capacity);
		_size = 0;
		_capacity = capacity;
	}
	void push(int x)
	{
		_a[_size++] = x;
	}

private:
	int* _a;
	int _size;
	int _capacity;
};
class MyQueue
{
public:
	MyQueue(int pushN, int popN)
	{}
private:
	stack _pushst;
	stack _popst;
	int _size;
};

在上面這份代碼中,我們編寫了一個MyQueue類,里面定義了兩個對象成員和一個整型成員變量,你是否想過,該如何初始化對象成員呢?由于stack中定義了缺省參數(shù),不需要傳參就可以完成構造,但如果你需要指定stack的capacity或者沒有缺省參數(shù)時,該怎么辦呢?

仔細思考,進入函數(shù)體后,成員變量的空間就已經(jīng)都開好了,所以在函數(shù)體中是無法完成初始化賦值的。而初始化列表就可以完美解決此問題。如下是初始化列表初始化對象的方式:
【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值),C++,c++,開發(fā)語言

以下三種類的成員,必須放在初始化列表的位置進行初始化

  • 引用成員變量
  • const成員變量
  • 自定義類型成員(且沒有默認構造函數(shù))
class A
{
public:
	A(int a)
		:_a(a)
	{}
private:
	int _a;
};
class B
{
public:
	B(int a, int& ref)
		:_aobj(a)
		, _ref(ref)
		, _n(10)
	{}
private:
	A _aobj; // 沒有默認構造函數(shù)
	int& _ref; // 引用
	const int _n; // const
};

建議:能在初始化列表中初始化就在初始化列表中初始化,因為不管你是否使用初始化列表,對于自定義類型成員變量,一定會先使用初始化列表初始化。

初始化列表的特點

  1. 初始化列表,不管寫沒寫,每個成員變量都會走一遍,而且在初始化列表中只能出現(xiàn)一次(初始化只能初始化一次)
  2. 對于自定義類型,會調(diào)用默認構造(沒有默認構造則報錯)。
  3. 先走初始化列表,再走函數(shù)體。
  4. 拷貝構造也有初始化列表
  5. 成員變量在類中聲明次序就是其在初始化列表中的初始化順序,與其在初始化列表中的先后次序無關。

對于第四點,我們可以使用一份代碼來證明:

【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值),C++,c++,開發(fā)語言

上面這份代碼,根據(jù)_a1和_a2的聲明順序,初始化列表先走的_a2,再走的_a1,導致在初始化_a2使用了未初始化_a1,故產(chǎn)生了隨機值,佐證了特點四。

隱式類型轉(zhuǎn)換

之前我們講過,不同類型的內(nèi)置類型變量在相互賦值時會有隱式類型轉(zhuǎn)換

double a = 10.5;
int b = a;

就如上面這個簡單的賦值,在a賦值給b之前,會產(chǎn)生一個臨時變量,最終賦給b值的就是這個臨時變量。

【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值),C++,c++,開發(fā)語言

當將不同類型的變量取引用時,需要加const的原因,是因為臨時變量具有常性。

臨時變量具有常性,其本質(zhì)就跟數(shù)字一樣如,1,2,3等,可以給變量賦值,正常情況下不能取到地址或者取到引用,除非用const修飾變量。

double a = 10.5;
// int& b = a;// 報錯
// int& c = 10;// 報錯
const int& b = a;// 正常運行
const int& c = 10;// 正常運行

上述代碼中b取的就是a產(chǎn)生的臨時變量的引用,臨時變量存儲在內(nèi)存的靜態(tài)區(qū),具有常性,就跟第四行代碼的數(shù)字10性質(zhì)是一樣的,當你加上const時,這種引用權限就被放開了,因為const確保了你不會對靜態(tài)區(qū)的變量做出改動。對于C++的自定義類型,與內(nèi)置類型遵循的規(guī)則是一樣的。

C++支持一種類型轉(zhuǎn)換式的構造:

class A
{
public:
	A(int a)
		:_a1(a)
	{}
	A(const A& aa)
		:_a1(aa._a1)
	{
		cout << "A(const A& aa)" << endl;
	}
private:
	int _a1;
	int _a2;
};
int main()
{
	A aa1(1);
	A aa2 = 1;
	return 0;
}

對于main函數(shù)第一行代碼是標準的調(diào)用了構造函數(shù)。而第二行,作為內(nèi)置類型的1,竟然能給對象的初始化賦值,這是因為在賦值之前,產(chǎn)生了隱式類型轉(zhuǎn)換,1作為一個參數(shù)傳遞給了構造函數(shù)從而產(chǎn)生了一個臨時對象,最終臨時變量拷貝構造給aa2

【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值),C++,c++,開發(fā)語言

在調(diào)用此代碼的過程中,我們發(fā)現(xiàn),并沒有調(diào)用拷貝構造函數(shù),這是因為通過編譯器的優(yōu)化省去了拷貝構造這一過程,簡單來說就是:

構造函數(shù) + 拷貝構造 + 編譯器優(yōu)化 = 構造函數(shù)

這時候看這兩行能否運行的原因應該就不困難了:

// A& ref = 10;// 報錯
const A& ref = 10;//可運行
// 這里ref引用的是類型轉(zhuǎn)換中用10構造的臨時對象

在上面代碼中,我們使用的構造函數(shù)一直是單參數(shù)的,可以使用特殊的隱式類型轉(zhuǎn)換構造。但是如果構造函數(shù)是多參數(shù)的,該怎么使用類似于A aa = 1;的方式創(chuàng)建對象呢?其實C++提供了解決方案,那就是多參數(shù)構造。

class A
{
public:
	A(int a1, int a2)
		:_a1(a1)
		, _a2(a2)
	{}
	A(const A& aa)
		:_a1(aa._a1)
		,_a2(aa._a2)
	{}
	void print()const
	{
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a1;
	int _a2;
};
// 多參數(shù)構造
int main()
{
	A aa1 = { 2,2 };
	aa1.print();
	// A& ref = { 2,3 };//報錯
	const A& ref = { 2,3 };
	ref.print();
	return 0;
}

【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值),C++,c++,開發(fā)語言

不過需要注意的是,只有C++11及其往后的版本才支持多參數(shù)構造。老版本,如C++98并不支持這樣創(chuàng)建對象。

explicit關鍵字

這個知識點稍稍提一下,如果不想允許構造時出現(xiàn)類的隱式類型轉(zhuǎn)換,可以在拷貝構造前加個explicit關鍵字,就可以成功限制類的隱式類型轉(zhuǎn)換了。

【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值),C++,c++,開發(fā)語言

關于explicit的更多使用,在后面有機會還會講。

成員變量缺省值

之前講過,在C++11的新標準中,支持為類中的成員變量提供缺省值。在類和對象中,提供的缺省值是提供給初始化列表使用的由于支持隱式類型轉(zhuǎn)換構造等原因,提供的缺省值可以非常靈活,見代碼:

class A
{
public:
	A(int a1)
		:_a1(a1)
	{
		cout << "A(int a1)" << endl;
	}
	A(int a1, int a2)
		:_a1(a1)
		, _a2(a2)
	{
		cout << "A(int a1, int a2)" << endl;
	}
	A(const A& aa)
		:_a1(aa._a1)
		, _a2(aa._a2)
	{
		cout << "A(const A& aa)" << endl;
	}
private:
	int _a1;
	int _a2;
};
class B
{
public:
private:
	int _b1 = 1;// 缺省值可以給整型變量
	int* ptr = (int*)malloc(40);// 可以開空間給指針
	A _aa1 = 1;// 可以給對象類型(A _aa1(1);這樣構造是錯誤的)
	A _aa2 = { 1,2 };// 多參數(shù)構造
	A _aa3 = _aa2;// 拷貝構造,缺省參數(shù)甚至可以是一個對象
};
int main()
{
	B bb1;
	return 0;
}

這些缺省參數(shù),最終都會提供給初始化列表。

如果顯示提供了初始化列表,運行時,這些被提供的缺省參數(shù)就會被忽略(簡單說就是:如果既提供了初始化列表,也有缺省值,編譯器默認使用初始化列表提供的值)。

結語

本篇博客將最后兩個默認成員函數(shù)做了一個收尾,再次談到了構造函數(shù)的一些語法和特性,關于初始化列表的概念和使用;一種很新的創(chuàng)建對象方式,隱式類型轉(zhuǎn)換方式創(chuàng)建對象,而explicit關鍵字可以限制這種轉(zhuǎn)換的發(fā)生;最后還提到了C++11的新特性成員變量的缺省值,列出了對象,指針等類型給缺省值的方式。在類和對象的下一篇,會再介紹幾個類和對象的小特性,以及編譯器做出的優(yōu)化。

博主還會繼續(xù)產(chǎn)出有趣的內(nèi)容,感謝大家的支持!?文章來源地址http://www.zghlxwxcb.cn/news/detail-858302.html

到了這里,關于【C++】類和對象④(類的默認成員函數(shù):取地址及const取地址重載 | 再談構造函數(shù):初始化列表,隱式類型轉(zhuǎn)換,缺省值)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包