事實上任何一個類,在我們不寫的情況下,都會自動生成6個默認(rèn)的成員函數(shù)。
1.構(gòu)造函數(shù)概念:
構(gòu)造函數(shù)是一個特殊的成員函數(shù),名字與類名相同,實例化對象時由編譯器自動調(diào)用,以此來保證每個數(shù)據(jù)成員都有一個合適的初始值,并且在對象的生命周期內(nèi)只調(diào)用一次。
構(gòu)造函數(shù)的主要作用是初始化對象,而不是開辟空間創(chuàng)建對象。
特征:
1.函數(shù)名與類名相同
2.創(chuàng)建對象時,由編譯器自動調(diào)用,用戶無法調(diào)用
3.無返回值(void也不可以)
4.構(gòu)造函數(shù)可以重載
5.若類中沒有顯式定義構(gòu)造函數(shù),則編譯器會自動生成一個無參的默認(rèn)構(gòu)造函數(shù);若用戶已顯式定義,則編譯器不再生成
6.無參和全缺省的構(gòu)造函數(shù)都稱為默認(rèn)構(gòu)造函數(shù),且默認(rèn)構(gòu)造函數(shù)只能有一個
例1:
例2:
例3:
2.析構(gòu)函數(shù)概念:
與構(gòu)造函數(shù)相反,析構(gòu)函數(shù)不是完成對象的銷毀,局部對象銷毀工作是由編譯器完成的,而對象在銷毀時,會自動調(diào)用析構(gòu)函數(shù),完成類的一些資源清理工作。
特性:
默認(rèn)的成員函數(shù),一定會生成?1.析構(gòu)函數(shù)名是在類名前加上一個字符‘~’。
2.沒有參數(shù)(可以加void,但一般不會這樣使用),沒有返回值。
3.一個類有且僅有一個析構(gòu)函數(shù)(不能重載)。若未顯式定義,系統(tǒng)則會自動生成默認(rèn)的析構(gòu)函數(shù)。
4.對象生命周期結(jié)束時,C++編譯系統(tǒng)會自動調(diào)用析構(gòu)函數(shù)。
從語法上來講,是一定會生成的,但是實際情況中并不一定。因為語法是靠人來具體實現(xiàn)的,有時需要考慮一些其他因素,比如程序的運行效率,所以有可能不會嚴(yán)格按照語法來實現(xiàn)。
? 比如一下代碼,并沒有什么意義,在某些編譯器及版本中(例:VS2013),就不會生成類的默認(rèn)成員函數(shù)。
3.拷貝構(gòu)造函數(shù)概念:
拷貝構(gòu)造函數(shù)只有單個形參,該形參是對本類類型對象的引用(一般常用const修飾,防止被修改),在用已存在的類類型對象創(chuàng)建新對象時,由編譯器自動調(diào)用。
特征:
1.拷貝構(gòu)造函數(shù)是構(gòu)造函數(shù)的一個重載形式
2.拷貝構(gòu)造函數(shù)的參數(shù)只有一個且必須使用引用傳參,使用傳值方式會引發(fā)無窮遞歸調(diào)用
3.若未顯式定義,系統(tǒng)會生成默認(rèn)的拷貝構(gòu)造函數(shù)。
注意:默認(rèn)的拷貝構(gòu)造函數(shù)對象按內(nèi)存存儲按字節(jié)序完成拷貝,這種拷貝屬于淺拷貝,或叫值拷貝;所以沒有涉及到資源管理,可以直接使用默認(rèn)的拷貝構(gòu)造函數(shù)。
為什么拷貝構(gòu)造函數(shù)使用傳值方式會引發(fā)無窮遞歸?? 那我們就假設(shè)可以使用傳值方式,那么在調(diào)用拷貝構(gòu)造函數(shù)時就會發(fā)生臨時拷貝,需要將實參拷貝到形參中,即通過實參來構(gòu)造形參對象,那么此時就又需要調(diào)用拷貝構(gòu)造函數(shù),因此陷入無窮遞歸調(diào)用。
什么情況需要自實現(xiàn)拷貝構(gòu)造函數(shù)?? 因為默認(rèn)的拷貝構(gòu)造函數(shù)采用的是淺拷貝,因此當(dāng)涉及到資源的管理時,就需要自實現(xiàn)拷貝構(gòu)造函數(shù)。
調(diào)用拷貝構(gòu)造函數(shù)的場景(1)用一個對象直接構(gòu)造一個新對象
(2)類類型對象,以值的形式傳參
(3)類類型對象,以值的方式作為函數(shù)返回值
注意:若直接創(chuàng)建返回一個匿名對象,編譯器不會通過拷貝構(gòu)造函數(shù)創(chuàng)建一個臨時對象返回,而是直接將匿名對象返回。
4.賦值運算符重載概念:
C++為了增強代碼的可讀性引入了運算符重載,運算符重載是具有特殊函數(shù)名的函數(shù),也具有其返回值類型、函數(shù)名,以及參數(shù)列表,其返回值類型與參數(shù)列表和普通的函數(shù)類似。
函數(shù)名:關(guān)鍵字operator后面接需要重載的運算符符號
函數(shù)原型:返回值類型? operator操作符(參數(shù)列表)
注意:
什么情況需要自實現(xiàn)賦值運算符重載?1.不能通過連接其他符號來創(chuàng)建新的操作符,比如operator@
2.重載操作符必須有一個類類型或者枚舉類型的操作數(shù)
3.用于內(nèi)置類型的操作符,其含義不能改變,例如:內(nèi)置的整型+,不能改變其含義
4.作為類成員的重載函數(shù)時,其形參看起來比操作數(shù)數(shù)目少一,其實成員函數(shù)的操作符有一個默認(rèn)的形參this,限定為第一個參數(shù)
5.以下五個運算符不能重載:.*、::、sizeof、?:、.
默認(rèn)的賦值運算符重載,也是采用的淺拷貝,所以如果類中未涉及到資源管理時,賦值操作是否顯示提供都可以,需要則提供,不需要則可不提供,利用編譯器完成賦值操作即可。
若類中涉及到資源管理,則用戶必須顯示實現(xiàn),否則編譯器默認(rèn)生成的賦值運算符重載實現(xiàn)采用的是淺拷貝,可能造成資源、內(nèi)存泄漏,和多個對象共享同一份資源,在銷毀時造成代碼崩潰。
為什么賦值運算符重載必須重載為類的成員函數(shù)?? 因為賦值運算符重載是類默認(rèn)的成員函數(shù),若用戶沒有顯示定義時,編譯器會自動生成一份,而此時若用戶自己再在類外實現(xiàn)一份,相等于存在兩個賦值運算符重載形成歧義,編譯器則會報錯。
較為標(biāo)準(zhǔn)的賦值運算符重載(1)加返回值,支持連續(xù)賦值
類類型對象賦值,相當(dāng)于是調(diào)用賦值運算符重載函數(shù),結(jié)合連續(xù)賦值的本質(zhì),所以需要對賦值運算符重載函數(shù)加返回值。
(2)返回引用(前提不影響功能實現(xiàn)),提高效率
返回引用,則返回時不需要再調(diào)用拷貝構(gòu)造函數(shù)構(gòu)造臨時對象,提高程序效率。
(3)引用傳參,提高效率
(4)const修飾參數(shù),防止參數(shù)對象被修改
(5)添加檢驗,防止本身給本身賦值
實現(xiàn)重載前置++與后置++因為++運算符是單目運算符,作為類的成員重載函數(shù),自帶了默認(rèn)的形參this,所以為了能夠?qū)崿F(xiàn)前置與后置++重載,在后置++重載函數(shù)中多加一個int形參作為區(qū)分。
注意:
后置++是先使用,再+1。所以需要先臨時保存對象,再對對象數(shù)據(jù)+1,然后返回的是+1前的臨時對象(即這里不可以返回引用)。
實現(xiàn)流提取運算符<<重載若重載為類的成員函數(shù):
? 語法上是可以的,但是因為其自帶默認(rèn)參數(shù)this,所以其使用邏輯為"對象名< <<重載規(guī)定: ? 第一個參數(shù)必須是ostream的對象,第二個參數(shù)才是要打印的內(nèi)容,所以一般重載為全局函數(shù)。 const修飾類的成員函數(shù): 將const修飾的類成員函數(shù)稱之為const成員函數(shù);const修飾類成員函數(shù),(本質(zhì))實際上修飾該成員函數(shù)隱藏的this指針,表明在該成員函數(shù)中不能對類的任何成員進行修改。 例: 比如以下函數(shù),本意只是想對時間進行一個打印輸出,但是在內(nèi)部可能不小心會對數(shù)據(jù)造成修改,影響功能實現(xiàn): this的類型:Time* const this 即this指針的指向不能修改,但是this指向?qū)ο笾械膬?nèi)容可以修改。 此時就可以通過const修飾該成員函數(shù),表明在該成員函數(shù)中不能對類的任何成員進行修改。 this的類型:const Time* const this 即this指針的指向不能修改,指向?qū)ο笾械膬?nèi)容也不能修改。 (1)const對象能否調(diào)用非const成員函數(shù)? ? 不能,const類型對象只能調(diào)用const成員函數(shù),不能調(diào)用普通成員函數(shù)。因為普通成員函數(shù)可能會對對象中的成員進行修改。 (2)非const對象能否調(diào)用const成員函數(shù)? ? 可以,普通對象對于普通成員函數(shù)和const成員函數(shù)都可以調(diào)用。 (3)const成員函數(shù)內(nèi),能否調(diào)用其他的非const成員函數(shù)? ? 不能,同理非const成員函數(shù)可能會對對象的成員進行修改,而const成員函數(shù)內(nèi)不能對對象的任何成員進行修改。 (4)非const成員函數(shù)內(nèi),能否調(diào)用其他的const成員函數(shù)? ? 可以。 注意: 構(gòu)造函數(shù),拷貝構(gòu)造函數(shù),析構(gòu)函數(shù),賦值運算符重載,不可以使用const修飾。因為以上四個函數(shù)目的就是對成員進行修改。 ? mutable關(guān)鍵字修飾成員變量,表示該成員變量可以在const修飾中被修改。 取地址操作符重載: const取地址操作符重載: 注意: 這兩個運算符一般使用編譯器生成的默認(rèn)取地址重載成員函數(shù)即可,一般不需要自己實現(xiàn)重載。只有特殊情況才需要自己實現(xiàn),比如想要讓別人獲取指定的內(nèi)容等。 你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)站欄目:C++程序設(shè)計——類的六個成員函數(shù)-創(chuàng)新互聯(lián)
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機、移動網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、外貿(mào)建站、用戶體驗、手機網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源:
創(chuàng)新互聯(lián)
相關(guān)問題
文章地址:http://aaarwkj.com/article30/csojso.html
猜你還喜歡下面的內(nèi)容