C++類與對象的詳細說明2
類的默認成員函數(shù)
每個類中,如果不主動實現(xiàn)默寫特定函數(shù),類中也會自動去生成這些函數(shù),它們就是默認成員函數(shù)。默認成員函數(shù)分為六種,它們是特殊的成員函數(shù),如果我們不實現(xiàn),編譯器會自己實現(xiàn)。
下面將對這些函數(shù)一 一進行介紹。
構(gòu)造函數(shù)
概念
構(gòu)造函數(shù)的作用即為初始化,相當(dāng)于平時我們自己寫的Init函數(shù),但在對象實例化時會自動調(diào)用,以保證實例化對象一定初始化。
特性
(1)函數(shù)名與類名相同
如日期類Date,其構(gòu)造函數(shù)名也為Date
(2)無返回值
以日期類為例,其構(gòu)造函數(shù)的聲明和定義可以寫成如下樣子:
class Date{public:Date(int year = 0, int month = 1, int day = 1);private:int _year;int _month;int _day;};class Date { public: Date(int year = 0, int month = 1, int day = 1); private: int _year; int _month; int _day; };
Date::Date(int year, int month, int day) { _year = year; _month = month; _day = day; }
(3)對象實例化時編譯器自動調(diào)用對應(yīng)的構(gòu)造函數(shù)
為了驗證這一點,我們創(chuàng)建一個對象,但不對其進行其它操作:
int main() { Date date1; return 0; }
通過調(diào)試可以發(fā)現(xiàn)對象date1已經(jīng)被自動初始化了。
(4)構(gòu)造函數(shù)可以重載
(5)如果類中沒有顯式定義構(gòu)造函數(shù),則C++編譯器會自動生成一個無參的默認構(gòu)造函數(shù),一旦用戶顯式定義,編譯器將不再自動生成。
(6)無參的構(gòu)造函數(shù)和全缺省的構(gòu)造函數(shù)都稱為默認構(gòu)造函數(shù),并且默認構(gòu)造函數(shù)只能有一個。
針對第五點,我們不免會發(fā)出疑問,編譯器自動生成的默認構(gòu)造函數(shù)究竟干了什么呢?
首先,需要先了解C++把類型分為兩類:內(nèi)置類型(基本類型)和自定義類型。
內(nèi)置類型就是C語言自帶的類型,如int、char、double、指針、內(nèi)置類型的數(shù)組;而自定義類型就是strucrt和class定義的類型。
編譯器默認生成的構(gòu)造函數(shù),對于成員變量中的內(nèi)置類型不做初始化,對于自定義類型成員變量則會調(diào)用它的默認構(gòu)造函數(shù)初始化,如果沒有默認構(gòu)造函數(shù)則會報錯。
析構(gòu)函數(shù)
概念
析構(gòu)函數(shù)的功能是完成對象中資源的清理。虛構(gòu)函數(shù)會在對象的生命周期到了之后調(diào)用。
特性
(1)析構(gòu)函數(shù)名是在類名前加上字符~。
(2)無參數(shù)無返回值。
日期類析構(gòu)函數(shù)的聲明可以寫成如下形式:
~Date();
(3)一個類有且只有一個析構(gòu)函數(shù)。若喂顯式定義,系統(tǒng)會自動生成默認的析構(gòu)函數(shù)。
(4)對象生命周期結(jié)束時,C++編譯系統(tǒng)自動調(diào)用析構(gòu)函數(shù)。
對于編譯器自動生成的默認析構(gòu)函數(shù),與構(gòu)造函數(shù)類似,對于內(nèi)置類型成員變量不做處理;對于自定義類型成員變量會去調(diào)用它的構(gòu)造函數(shù)。
拷貝構(gòu)造函數(shù)
概念
拷貝構(gòu)造函數(shù)用于使用同類型對象去初始化實例對象。
特征
(1)拷貝構(gòu)造函數(shù)是構(gòu)造函數(shù)的一個重載形式。
(2)拷貝構(gòu)造函數(shù)的參數(shù)只有一個且必須使用引用傳參,使用傳值的方式會引發(fā)無窮遞歸調(diào)用。
日期類拷貝構(gòu)造函數(shù)的聲明需要寫成如下形式:
Date(Date& date);
為什么必須采用引用傳參呢?引發(fā)無窮遞歸又是怎么一回事呢?
不妨來思考一下,傳參實際上也是對內(nèi)容進行臨時拷貝,將實參傳給形參本身就需要調(diào)用拷貝構(gòu)造。由此一來,會導(dǎo)致不斷調(diào)用拷貝構(gòu)造,造成無窮遞歸調(diào)用。
(3)若未顯式定義,系統(tǒng)會生成默認的拷貝構(gòu)造函數(shù)了。
默認拷貝構(gòu)造函數(shù)對于內(nèi)置類型成員,會完成按字節(jié)序的拷貝(淺拷貝),如果需要深拷貝則需要自己寫拷貝構(gòu)造函數(shù);對于自定義類型成員,則會調(diào)用它的拷貝構(gòu)造函數(shù)。
所謂按字節(jié)序拷貝指將內(nèi)存中的內(nèi)容照搬照抄,復(fù)制過來。在一些情況下就會出錯,如存放申請內(nèi)存地址的指針,如果按字節(jié)序拷貝,會導(dǎo)致兩個對象中的成員變量指向同一塊空間,在析構(gòu)時會導(dǎo)致同一塊空間釋放內(nèi)存多次,引發(fā)錯誤。
賦值運算符重載
運算符重載
在談及賦值運算符重載前,必須先來講一講運算符重載。
我們知道,對于int類型,是可以進行加減乘除等運算的。但對于自定義類型,能否實現(xiàn)加減乘除運算呢?這就需要運用到運算符重載了。
運算符重載是具有特殊函數(shù)名的函數(shù)。函數(shù)名字為:operator操作符(參數(shù)列表)
注意:一些運算符不支持重載,即:.*、::、sizeof、?:、.
以Date類==運算符重載為例,需要將函數(shù)作為成員函數(shù),以便于訪問成員變量:
class Date { public: Date(int year = 0, int month = 1, int day = 1); bool operator==(Date& date)const; private: int _year; int _month; int _day; }; bool Date::operator==(Date& date)const { return _year == date._year && _month == date._month && _day == date._day; }
賦值運算符重載
賦值運算符重載顧名思義,是對賦值運算符進行的重載,用于兩個已經(jīng)存在的對象進行賦值拷貝。
賦值運算符重載有四個要點:
(1)參數(shù)類型
(2)返回值
(3)檢測是否自己給自己賦值
(4)返回*this,用于連續(xù)賦值
一個類如果沒有顯式定義賦值運算符重載,編譯器會自己生成一個,對于內(nèi)置成員,完成按字節(jié)序拷貝;對于自定義成員變量,會調(diào)用它的賦值運算符重載。
取地址及const取地址操作符重載
這兩個運算符一般不需要重新定義,使用編譯器生成的重載即可,只有特殊情況才需要重載,如不希望自己特定的內(nèi)容被別人訪問時。
總結(jié)
篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C 程序?qū)崿F(xiàn)密碼隱秘輸入的實例 linux系統(tǒng)可執(zhí)行
下面小編就為大家?guī)硪黄狢 程序?qū)崿F(xiàn)密碼隱秘輸入的實例 linux系統(tǒng)可執(zhí)行。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11C++編程析構(gòu)函數(shù)拷貝構(gòu)造函數(shù)使用示例詳解
這篇文章主要為大家介紹了C++編程構(gòu)造函數(shù)中析構(gòu)函數(shù)及拷貝構(gòu)造函數(shù)的使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11Visual?Studio?2022下載及配置OpenCV4.5.5的詳細過程
這篇文章主要介紹了Visual?Studio?2022下載及配置OpenCV4.5.5的詳細過程,在這里注意下Win10的64位操作系統(tǒng),在OpenCV官網(wǎng)下載OpenCV4.5.5,安裝的是Win?pack,本文通過圖文并茂的形式給大家介紹的非常詳細,需要的朋友可以參考下2022-05-05