中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

手機網(wǎng)站建設(shè) 豆丁關(guān)鍵詞挖掘長尾詞工具

手機網(wǎng)站建設(shè) 豆丁,關(guān)鍵詞挖掘長尾詞工具,鐘樓做網(wǎng)站,廣州網(wǎng)頁設(shè)計公司招聘本文已收錄至《C語言》專欄! 作者:ARMCSKGT 目錄 前言 正文 構(gòu)造函數(shù) 對比C和C的初始化 構(gòu)造函數(shù)的使用與特性 默認(rèn)構(gòu)造函數(shù) C11關(guān)于默認(rèn)構(gòu)造缺陷的補丁 析構(gòu)函數(shù) 析構(gòu)函數(shù)特性 默認(rèn)析構(gòu)和自定義析構(gòu) 拷貝構(gòu)造函數(shù) 問題聚焦 拷貝構(gòu)造的定…

? ? ??

本文已收錄至《C++語言》專欄!
作者:ARMCSKGT

? ? ??


目錄

前言?

正文

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

對比C和C++的初始化

構(gòu)造函數(shù)的使用與特性

默認(rèn)構(gòu)造函數(shù)

C++11關(guān)于默認(rèn)構(gòu)造缺陷的補丁

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

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

默認(rèn)析構(gòu)和自定義析構(gòu)

拷貝構(gòu)造函數(shù)

問題聚焦?

拷貝構(gòu)造的定義和特性

使用場景

構(gòu)造函數(shù)小結(jié)

運算符重載

定義方式

特性

使用說明

運算符重載原理

賦值運算符重載

前后置++和--

const修飾this

取地址重載和const取地址重載

最后


前言?

C++類在設(shè)計之時,規(guī)定類中有六個默認(rèn)的成員函數(shù),這些成員函數(shù)天生就存在,而且功能都很強大,類和對象的關(guān)鍵點就在這六個默認(rèn)成員函數(shù)的學(xué)習(xí),本篇將會逐一介紹這六個成員函數(shù),讓我們向類和對象的深處出發(fā)!


正文

C++規(guī)定在每個類中有六個默認(rèn)函數(shù)成員:

函數(shù)功能重要性
構(gòu)造函數(shù)定義和初始化成員變量重要
析構(gòu)函數(shù)釋放申請的內(nèi)存空間(銷毀成員變量)重要
拷貝構(gòu)造(函數(shù))實現(xiàn)對象間的深拷貝重要
賦值重載(函數(shù))實現(xiàn)對象間的深賦值重要
取地址重載(函數(shù))自定義類對象取地址操作符功能一般
const取地址重載(函數(shù))自定義對象取地址操作符功能const修飾返回的地址一般

這些函數(shù)我們不寫,編譯器也會自己寫一個默認(rèn)的函數(shù)代替對應(yīng)函數(shù)!

//以日期類的方式初見六大默認(rèn)成員函數(shù)
class Date
{
public://構(gòu)造函數(shù)Date(size_t year = 1970, size_t month = 1, size_t day = 1){_year = year;_month = month;_day = day;}//析構(gòu)函數(shù)~Date(){_year = 0;_month = 0;_day = 0;}//拷貝構(gòu)造函數(shù)(簡稱:拷貝構(gòu)造)Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}//賦值重載函數(shù)(賦值運算符重載)Date& operator=(const Date& d){_year = d._year;_month = d._month;_day = d._day;return *this;}//取地址運算符重載Date* operator&(){return this;}//const返回取地址運算符重載,const修飾thisconst Date* operator&() const{return this;}private:size_t _year;size_t _month;size_t _day;};


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


對比C和C++的初始化

我們在使用C語言實現(xiàn)一些例如順序表,棧等簡單數(shù)據(jù)結(jié)構(gòu)時,一般都會寫一個初始化函數(shù)Init,防止野指針訪問,但這樣很容易讓我們忘記去調(diào)用!

?

在C++中,為了避免這種事情,引入了構(gòu)造函數(shù),在對象實例化時編譯器自動調(diào)用構(gòu)造函數(shù)進行初始化,所以構(gòu)造函數(shù)是為對象自動初始化而生的!

?

我們以日期對象為例,對比C與C++的初始化方案:

//C語言實現(xiàn)日期功能
typedef struct C_Date //日期數(shù)據(jù)結(jié)構(gòu)體
{size_t _year;size_t _month;size_t _day;
}C_Date;void InitDate(C_Date* L)//初始化函數(shù)
{L->_year = 0;L->_month = 0;L->_day = 0;
}
//C++實現(xiàn)日期類
class CPP_Date //日期對象
{
public://默認(rèn)構(gòu)造CPP_Date(size_t year){_year = year;_month = 1;_day = 1;}//重載實現(xiàn)多種默認(rèn)構(gòu)造方式CPP_Date(size_t year, size_t month, size_t day){_year = year;_month = month;_day = day;}private:size_t _year;size_t _month;size_t _day;
};

可以發(fā)現(xiàn)C++中類融入構(gòu)造函數(shù)后只需要實例化對象就能同時完成初始化,非常方便!而且結(jié)合C++的缺少參數(shù),函數(shù)重載等新特性,可以讓初始化豐富多樣,增強程序可用性!

??

對比C與C++,可以發(fā)現(xiàn)C++非常貼心,就像汽車中的手動擋與自動擋,但兩者在不同場合各有千秋,在程序開發(fā)上C++的更勝一籌,在較為底層且需要更細(xì)節(jié)的程序控制時C語言更勝一籌!不過一般在程序開發(fā)中,C與C++可以搭配一起編程!


構(gòu)造函數(shù)的使用與特性

構(gòu)造函數(shù)是一個特殊的成員函數(shù),名字與類名相同,創(chuàng)建類類型對象時由編譯器自動調(diào)用,以保證每個數(shù)據(jù)成員都有 一個合適的初始值,并且在對象整個生命周期內(nèi)只調(diào)用一次(實例化時被編譯器調(diào)用)。

?

構(gòu)造函數(shù)是特殊的成員函數(shù),需要注意的是,構(gòu)造函數(shù)雖然名稱叫構(gòu)造,但是構(gòu)造函數(shù)的主要任務(wù)并不是開空間創(chuàng)建對象,而是初始化對象成員變量。
?

構(gòu)造函數(shù)的定義方式:

class Test
{
public: //構(gòu)造函數(shù)必須公開Test(參數(shù)) {}  //構(gòu)造函數(shù)的函數(shù)名與類名相同且沒有返回值
};

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

  • 函數(shù)名與類名相同。
  • 無返回值(不需要寫返回值類型,void也不需要寫)。
  • 對象實例化時編譯器自動調(diào)用對應(yīng)的構(gòu)造函數(shù)。
  • 構(gòu)造函數(shù)可以重載,支持多個構(gòu)造函數(shù),但是默認(rèn)的構(gòu)造函數(shù)只有一個。

使用構(gòu)造函數(shù)初始化日期對象:

//C++實現(xiàn)日期類
class CPP_Date //日期對象
{
public://默認(rèn)構(gòu)造函數(shù)只允許出現(xiàn)一種顯示,如果定義全缺省就可以代替默認(rèn)構(gòu)造了//CPP_Date()//默認(rèn)構(gòu)造函數(shù)初始化-功能比較局限//{//	_year = 0;//	_month = 0;//	_day = 0;//}//構(gòu)造函數(shù)可以重載實現(xiàn)多種構(gòu)造方式CPP_Date(size_t year){_year = year;_month = 1;_day = 1;}//一般使用全缺省值方式代替默認(rèn)構(gòu)造-智能方便CPP_Date(size_t year = 1970, size_t month = 1, size_t day = 1){_year = year;_month = month;_day = day;}private:size_t _year;size_t _month;size_t _day;
};int main()
{//CPP_Date d(); //注意:這種調(diào)用默認(rèn)構(gòu)造的方式是錯誤的,調(diào)用默認(rèn)構(gòu)造不需要加()CPP_Date d1;CPP_Date d2(2022);CPP_Date d3(2023,3,12);//可以通過調(diào)用不同的構(gòu)造函數(shù)實例化多個不同的對象
}


默認(rèn)構(gòu)造函數(shù)

如果類中沒有顯式定義構(gòu)造函數(shù),則C++編譯器會自動生成一個無參的默認(rèn)構(gòu)造函數(shù),一旦
用戶顯式定義編譯器將不再生成。

那有人可能會問,既然編譯器會自動生成構(gòu)造函數(shù),我們?yōu)槭裁催€要去寫?

注意:編譯器生成的默認(rèn)構(gòu)造函數(shù),對內(nèi)置類型不做處理,對自定義類型會調(diào)用該對象的構(gòu)造函數(shù)!

數(shù)據(jù)類型區(qū)分

  • 內(nèi)置類型:int,char,double等。
  • 自定義類型:struct,class等,這些自定義類型可以有自己的默認(rèn)構(gòu)造函數(shù)。

編譯器默認(rèn)構(gòu)造對內(nèi)置類型的初始化:?

編譯器默認(rèn)構(gòu)造初始化內(nèi)置類型

自定義默認(rèn)構(gòu)造:

//C++實現(xiàn)日期類
class CPP_Date //日期對象
{
public://無參構(gòu)造函數(shù)//CPP_Date()//{//	_year = 0;//	_month = 0;//	_day = 0;//}//全缺省默認(rèn)構(gòu)造CPP_Date(size_t year = 1970, size_t month = 1, size_t day = 1){_year = year;_month = month;_day = day;}//當(dāng)存在兩種實例化相同的構(gòu)造方法時,只能存在一種,否則在調(diào)用時會出錯!//例如 (CPP_Date d;) 編譯器無法判斷d對象調(diào)用的是哪一個構(gòu)造函數(shù)private:size_t _year;size_t _month;size_t _day;
};
自定義默認(rèn)構(gòu)造完成內(nèi)置類型的初始化

??

無參的構(gòu)造函數(shù)和全缺省的構(gòu)造函數(shù)都稱為默認(rèn)構(gòu)造函數(shù),并且默認(rèn)構(gòu)造函數(shù)只能有一個。

?
注意:無參構(gòu)造函數(shù)、全缺省構(gòu)造函數(shù)、我們沒寫編譯器默認(rèn)生成的構(gòu)造函數(shù),都可以認(rèn)為是默認(rèn)構(gòu)造函數(shù)。


C++11關(guān)于默認(rèn)構(gòu)造缺陷的補丁

為了解決內(nèi)置類型無法被編譯器生成的默認(rèn)構(gòu)造初始化的問題,在C++11中支持內(nèi)置類型在聲明階段給缺省值,當(dāng)編譯器生成默認(rèn)構(gòu)造函數(shù)時,使用這些缺省值初始化內(nèi)置類型。

class CPP_Date //日期對象
{
public:private:size_t _year = 1970; //聲明階段賦予缺省值size_t _month = 1;size_t _day = 1;//注意:類成員變量定義在構(gòu)造函數(shù)的初始化列表,并不是在聲明階段!
};


所以,對于內(nèi)置類型要么自定義默認(rèn)構(gòu)造函數(shù),或者在聲明時賦予缺省值,對于自定義類型編譯器會調(diào)用對應(yīng)的構(gòu)造函數(shù)!


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


我們在寫順序表時,在結(jié)束使用時需要調(diào)用銷毀函數(shù)是否內(nèi)存空間,但是我們可能經(jīng)常也會忘記釋放空間,析構(gòu)函數(shù)就是用來銷毀對象和釋放空間的

??

析構(gòu)函數(shù)是特殊的成員函數(shù),其功能與構(gòu)造函數(shù)相反,析構(gòu)函數(shù)不是完成對對象本身的銷毀,局部對象銷毀工作是由編譯器完成的。而對象在銷毀時(生命周期結(jié)束時)會自動調(diào)用析構(gòu)函數(shù),完成對象中資源的清理工作。


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

  • 析構(gòu)函數(shù)名是在類名前加上字符 ~。
  • 無參數(shù)無返回值類型(void也不需要寫)。
  • 一個類只能有一個析構(gòu)函數(shù)。若未顯式定義,系統(tǒng)會自動生成默認(rèn)的析構(gòu)函數(shù)。
  • 析構(gòu)函數(shù)不能重載。
  • 對象生命周期結(jié)束時,C++編譯系統(tǒng)系統(tǒng)自動調(diào)用析構(gòu)函數(shù)。
    ? ?

對于析構(gòu)函數(shù),最大的特性是在對象生命周期結(jié)束時被自動調(diào)用,與構(gòu)造函數(shù)的區(qū)別在于不支持重載,也就是說一個對象只能有一個析構(gòu)函數(shù)!


默認(rèn)析構(gòu)和自定義析構(gòu)

??

如果我們不寫析構(gòu)函數(shù),編譯器也會默認(rèn)生成,但編譯器生成的析構(gòu)函數(shù)對內(nèi)置類型仍然不做處理,對自定義類型會調(diào)用對應(yīng)的析構(gòu)函數(shù)處理

?

//析構(gòu)函數(shù)定義
class Test
{~Test() {//釋放方法}
};
//簡易棧對象
typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 3){_array = (DataType*)malloc(sizeof(DataType) * capacity);if (NULL == _array){perror("malloc申請空間失敗!!!");return;}_capacity = capacity;_size = 0;cout << "構(gòu)造函數(shù)初始化棧對象" << endl;}void Push(DataType data){// CheckCapacity();_array[_size] = data;_size++;}// 其他方法...~Stack(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}cout << "析構(gòu)函數(shù)釋放棧對象空間" << endl;}
private:DataType* _array;int _capacity;int _size;
};

對于自定義類型和內(nèi)置類型,是否存在析構(gòu)函數(shù)進行釋放影響都不大,當(dāng)涉及我們自己動態(tài)開辟空間時,就需要使用析構(gòu)函數(shù)釋放空間


注意:創(chuàng)建哪個類的對象則調(diào)用該類的析構(gòu)函數(shù),銷毀那個類的對象則調(diào)用該類的析構(gòu)函數(shù)!對于析構(gòu)函數(shù),只要是對象中涉及動態(tài)內(nèi)存申請,則需要使用析構(gòu)函數(shù)釋放!


拷貝構(gòu)造函數(shù)


拷貝構(gòu)造也是構(gòu)造函數(shù)的一種,但是參數(shù)不同則構(gòu)成重載,功能和特性與構(gòu)造函數(shù)不同!


問題聚焦?

我們在創(chuàng)建對象時,如果需要拷貝一個一模一樣的對象,也就是復(fù)制一個對象;那么就需要創(chuàng)建一個一模一樣的對象后將數(shù)據(jù)拷貝一份過去。

編譯器默認(rèn)生成的拷貝構(gòu)造函數(shù)只支持淺拷貝,也就是值拷貝,對于內(nèi)置類型,淺拷貝是沒有影響的,但是如果對象中申請了空間,那么該對象中必定有一個指針指向該空間的首地址,淺拷貝只會講該地址拷貝一份給另一個對象,那么會導(dǎo)致一個嚴(yán)重的問題,就是兩個對象申請的空間是同一個地址,在增刪查改和析構(gòu)時拷貝的對象析構(gòu)函數(shù)會對同一片空間進行修改和重復(fù)釋放一片空間導(dǎo)致異常,最后成為野指針問題

淺拷貝只是簡單的逐字節(jié)拷貝,對于對象內(nèi)部有空間申請的,會發(fā)生共用空間重復(fù)析構(gòu)的情況;而深拷貝是在新對象中開辟一塊屬于自己的新空間,然后將數(shù)據(jù)逐一拷貝過來,新舊對象之間的數(shù)據(jù)相互獨立!

?

淺拷貝下對象共用一塊空間


拷貝構(gòu)造的定義和特性

??

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

? ?

特性

  • 拷貝構(gòu)造函數(shù)是構(gòu)造函數(shù)的一個重載形式。
  • 拷貝構(gòu)造函數(shù)的參數(shù)只有一個且必須是類類型對象的引用,使用傳值方式編譯器直接報錯,因為會引發(fā)無窮遞歸調(diào)用。
    ?

定義和調(diào)用

class Test
{//拷貝構(gòu)造形參的定義方式是唯一的:(const 類型& )Test(const Test& T) {//拷貝方法} //定義方式
};int main()
{Test t1;Test t2(t1); //調(diào)用拷貝構(gòu)造方式一Test t3 = t2; //調(diào)用拷貝構(gòu)造方式二return 0;
}

? ?

定義須知

  • 編譯器默認(rèn)生成的拷貝構(gòu)造,只是簡單拷貝,只能用于非動態(tài)內(nèi)存開辟的空間
  • 拷貝構(gòu)造的參數(shù)定義方式是唯一的??
  • 拷貝構(gòu)造函數(shù)函數(shù)名與構(gòu)造函數(shù)相同,不過參數(shù)類型為類對象的引用,不加引用則會發(fā)生無窮拷貝(因為形參是拷貝而來的,這樣形參會陷入無限遞歸拷貝形參)
形參無窮遞歸拷貝

使用場景

//日期類示例
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// Date(const Date& d) // 正確寫法Date(const Date& d) // 錯誤寫法:編譯報錯,會引發(fā)無窮遞歸{_year = d._year;_month = d._month;_day = d._day;}
private:int _year;int _month;int _day;
};int main()
{Date d1;Date d2(d1); //拷貝構(gòu)造方式一Date d3 = d2; //拷貝構(gòu)造方式二return 0;
}

像日期類這樣沒有動態(tài)內(nèi)存申請的對象,使用編譯器默認(rèn)生成的拷貝構(gòu)造進行淺拷貝即可,但是向數(shù)據(jù)結(jié)構(gòu)需要動態(tài)內(nèi)存申請等相對復(fù)雜的對象,就需要自定義拷貝構(gòu)造實現(xiàn)深拷貝

? ??

拷貝構(gòu)造函數(shù)典型調(diào)用場景

  • 使用已存在對象創(chuàng)建新對象
  • 函數(shù)參數(shù)類型為類類型對象
  • 函數(shù)返回值類型為類類型對象

說明

  • 對于深拷貝,是有一定代價的,為了提高程序效率,一般對象傳參時,盡量使用引用類型,返回時根據(jù)實際場景,能用引用盡量使用引用!
  • 默認(rèn)拷貝構(gòu)造函數(shù)與默認(rèn)構(gòu)造函數(shù)名相同,當(dāng)我們只寫拷貝而不寫構(gòu)造時,編譯器就會報錯,因為此時的拷貝會被誤以為是默認(rèn)構(gòu)造函數(shù)也就是說,默認(rèn)拷貝構(gòu)造函數(shù)存在的前提是默認(rèn)構(gòu)造函數(shù)已存在。

構(gòu)造函數(shù)小結(jié)


構(gòu)造大家族到這里基本內(nèi)容就介紹的差不多了!

類型用途處理情況
構(gòu)造函數(shù)初始化對象不對內(nèi)置類型作處理,自定義類型調(diào)用對應(yīng)構(gòu)造函數(shù)
析構(gòu)函數(shù)銷毀對象也不對內(nèi)置類型作處理,自定義類型調(diào)用對應(yīng)析構(gòu)函數(shù)
拷貝構(gòu)造函數(shù)拷貝對象只能對簡單內(nèi)置類型做處理,自定義類型需要自己實現(xiàn)深拷貝

運算符重載


C++為了增強代碼的可讀性引入了運算符重載,運算符重載是具有特殊函數(shù)名的函數(shù),也具有其返回值類型,函數(shù)名字以及參數(shù)列表,其返回值類型與參數(shù)列表與普通的函數(shù)類似。

運算符重載的引入,主要是為了解決基本運算符功能不足以滿足自定義類型需求的情況,例如日期類的加減,以及前后置++和--等,需要自定義對象運算符的功能!


定義方式

返回值類型 operator操作符(參數(shù))
{//自定義操作符功能
}// operator 是運算符重載的關(guān)鍵字

特性

  • 不能通過連接其他符號來創(chuàng)建新的操作符:比如operator@

  • 重載操作符必須有一個類類型參數(shù)

  • 用于內(nèi)置類型的運算符,其含義不能改變,例如:內(nèi)置的整型+,不 能改變其含義

  • 作為類成員函數(shù)重載時,其形參看起來比操作數(shù)數(shù)目少一個,因為成員函數(shù)的第一個參數(shù)為隱藏的this

  • 對于內(nèi)置運算符,不能改變其含義

  • ?operator操作符 就是函數(shù)名

  • 注意這5個運算符不能重載:(1)?.*?,(2)?:: ,(3)sizeof,(4)?:,(5)?.?


//日期類
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//為了保證封裝性,類成員變量一般是私有,所以運算符重載一般定義在類內(nèi)部bool operator==(const Date& d){//這里相當(dāng)于 *this 與 d 的 == 比較return _year == d._year&& _month == d._month&& _day == d._day;}private:int _year;int _month;int _day;
};int main()
{Date d1(2018, 9, 26);Date d2(2018, 9, 27);cout << (d1 == d2) << endl; //這里相當(dāng)于調(diào)用 d1.operator==(d2)return 0;
}

使用說明

  • operator 函數(shù)中的操作數(shù)取決于參數(shù)個數(shù)
  • operator 一般定義在類中,方便訪問類成員,當(dāng)定義在類中時,運算符左邊的對象默認(rèn)是*this
  • operator 如果定義在類外,則無法訪問類的所有成員,此時要么在類中定義特定函數(shù)獲取私有成員要么聲明為友元函數(shù),但是大部分場景下都沒有定義在類中更合適

運算符重載原理

運算符重載的原理與函數(shù)重載原理基本相同,也是對函數(shù)名修飾。

如果定義在類中在Linux環(huán)境下修飾規(guī)則為:_ZN4D+類名+運算符英文簡稱+ERKS_


賦值運算符重載

通過上面的鋪墊,我們就要介紹下一個默認(rèn)成員,那就是賦值重載函數(shù)!

class Test
{};

賦值重載是將一個對象賦值給另一個對象,與拷貝構(gòu)造相似,但是拷貝構(gòu)造是通過一個對象去實例化一個相同的對象,而賦值重載的前提是兩個對象已經(jīng)實例化存在,相互之間再賦值!本質(zhì)區(qū)別在于:一個是對象尚未實例化,另一個是兩個對象都已存在!當(dāng)兩個對象都被創(chuàng)建,并發(fā)生賦值行為時,才叫做賦值重載!

??

對于這種自定義類型復(fù)制的問題,就會涉及深拷貝和淺拷貝的問題,所以賦值重載是很有必要的!

//日期類
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}Date& operator=(const Date& d) //與拷貝構(gòu)造一樣能用引用就用引用{if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this; //返回賦值的對象的引用(也就是自己)//這里之所以返回自己的引用是因為會發(fā)生 d1 = d2 = d3 這樣連等的情況//使用引用可以有效避免拷貝}private:int _year;int _month;int _day;
};

賦值運算符重載格式

  • 參數(shù)類型:const T&,傳遞引用可以提高傳參效率
  • 返回值類型:T&,返回引用可以提高返回的效率,有返回值目的是為了支持連續(xù)賦值
  • 檢測是否自己給自己賦值
  • 返回*this :要復(fù)合連續(xù)賦值的含義
  • 賦值運算符只能重載成類的成員函數(shù)不能重載成全局函數(shù)

如果賦值運算符重載成全局函數(shù),就沒有this指針了,需要給兩個參數(shù),而且此時編譯器就會報錯error C2801: “operator =”必須是非靜態(tài)成員!

??
原因:賦值運算符如果不顯式實現(xiàn),編譯器會生成一個默認(rèn)的。此時用戶再在類外自己實現(xiàn)一個全局的賦值運算符重載,就和編譯器在類中生成的默認(rèn)賦值運算符重載沖突了,故賦值運算符重載只能是類的成員函數(shù)。

?默認(rèn)賦值重載函數(shù):用戶沒有顯式實現(xiàn)時,編譯器會生成一個默認(rèn)賦值運算符重載,以值的方式逐字節(jié)拷貝。

??

注意:內(nèi)置類型成員變量是直接賦值的,而自定義類型成員變量需要調(diào)用對應(yīng)類的賦值運算符重載完成賦值。

??

所以賦值重載的使用環(huán)境與拷貝構(gòu)造類似:如果類中未涉及到動態(tài)內(nèi)存申請(資源管理),賦值運算符是否實現(xiàn)都可以;一旦涉及到資源管理則必須要實現(xiàn)!

//棧對象 - 猜猜是否會發(fā)生與拷貝構(gòu)造相同的問題
typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 10){_array = (DataType*)malloc(capacity * sizeof(DataType));if (nullptr == _array){perror("malloc申請空間失敗");return;}_size = 0;_capacity = capacity;}void Push(const DataType& data){// CheckCapacity();_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}
private:DataType* _array;size_t _size;size_t _capacity;
};int main()
{Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2;s2 = s1;return 0;
}


前后置++和--

對于自定義對象,前后置++和--還是經(jīng)常會使用到的!

class Test
{Test& operator++() {}  //前置++Test operator++(int) {} //后置++Test& operator--() {}  //前置--Test operator--(int) {} //后置--
};
//以日期類進行介紹
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// 前置++:返回+1之后的結(jié)果
// 注意:this指向的對象函數(shù)結(jié)束后不會銷毀,故以引用方式返回提高效率Date& operator++(){_day += 1;return *this;}// 后置++:
// 注意:后置++是自己+1然后返回+1之前的值
// 而temp是臨時對象,因此只能以值的方式返回,不能返回引用Date operator++(int){Date temp(*this);_day += 1;return temp;}
private:int _year;int _month;int _day;
};int main()
{Date d1;d1++;++d1;return 0;
}

原理:前置++和后置++都是一元運算符,為了讓前置++與后置++形成能正確重載,C++規(guī)定:后置++重載時多增加一個int類型的參數(shù),但調(diào)用函數(shù)時該參數(shù)不用傳遞,編譯器自動傳遞(前后置--實現(xiàn)與++相同)。


const修飾this


將const修飾的“成員函數(shù)”稱之為const成員函數(shù),const修飾類成員函數(shù),實際修飾該成員函數(shù)隱含的this指針,表明在該成員函數(shù)中不能對類的任何成員進行修改。

?

const常被用來修飾引用和指針,使用const修飾可以提高程序的健壯性!

使用場景

  • 被(指針)指向?qū)ο笫浅A粱蚺R時變量
  • 被引用對象是常亮或臨時變量

這些對象必須使用const修飾,避免權(quán)限放大的問題!


修飾this指針格式

有小伙伴可能會疑惑,this指針我們不能顯示定義,那么如果要const修飾怎么辦?

對于this指針的修飾,格式為:

class Test
{void Fun() const //將const加在函數(shù)參數(shù)后即可{//函數(shù)方法}  
};
//設(shè)想以下日期類代碼的運行結(jié)果
class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << "Print()" << endl;cout << "year:" << _year << endl;cout << "month:" << _month << endl;cout << "day:" << _day << endl << endl;}void Print() const{cout << "Print()const" << endl;cout << "year:" << _year << endl;cout << "month:" << _month << endl;cout << "day:" << _day << endl << endl;}
private:int _year; // 年int _month; // 月int _day; // 日
};int main()
{Date d1(2022, 1, 13);d1.Print();const Date d2(2022, 1, 13);d2.Print();return 0;
}
代碼運行結(jié)果

總之,const修飾this指針可以起到權(quán)限平移的作用!


取地址重載和const取地址重載


這兩個默認(rèn)成員函數(shù)一般不用重新定義 ,編譯器默認(rèn)會生成。

class Date
{
public:Date* operator&() //返回對象的地址{return this;}const Date* operator&() const //返回const修飾對象的地址{return this;}
private:int _year; // 年int _month; // 月int _day; // 日
};

這兩個運算符一般不需要重載,使用編譯器生成的默認(rèn)取地址的重載即可,只有特殊情況,才需要重載,比如想讓別人獲取到指定的內(nèi)容!


最后

以上就是 類和對象 - 中 的全部內(nèi)容了,本篇介紹了類的六大默認(rèn)成員函數(shù),對于構(gòu)造函數(shù)何時用編譯器自動生成的,何時自己實現(xiàn)都需要依照情況而定!對于每個成員其規(guī)則和細(xì)節(jié)都很多,需要我們在長期的使用中去牢固的掌握,掌握了這六大成員函數(shù)的使用,那么你將對類和對象的掌握又進一步!

本次 <C++類和對象 - 中> 就介紹到這里啦,希望能夠盡可能幫助到大家。

如果文章中有瑕疵,還請各位大佬細(xì)心點評和留言,我將立即修補錯誤,謝謝!

🌟其他文章閱讀推薦🌟

C++ 類和對象 - 上

C++ 入門知識

數(shù)據(jù)結(jié)構(gòu)初階?<棧>

🌹歡迎讀者多多瀏覽多多支持!🌹

http://m.risenshineclean.com/news/42539.html

相關(guān)文章:

  • 為什么選php語言做網(wǎng)站手機百度網(wǎng)盤下載慢怎么解決
  • 三級分銷網(wǎng)站制作打開網(wǎng)址資料網(wǎng)站
  • 政府集約化網(wǎng)站群建設(shè)aso推廣公司
  • 鄭州小程序制作流程及費用aso優(yōu)化服務(wù)
  • 網(wǎng)站頁面設(shè)計風(fēng)格今日網(wǎng)站收錄查詢
  • 德陽企業(yè)品牌網(wǎng)站建設(shè)引流推廣廣告怎么寫
  • 怎么利用網(wǎng)站做cpa推廣傳播易廣告投放平臺
  • 網(wǎng)站必須備案嗎社群營銷怎么做
  • 我要自學(xué)網(wǎng)ps視頻教程免費寧波網(wǎng)站優(yōu)化公司哪家好
  • 自己開發(fā)一款游戲怎么做搜索引擎seo優(yōu)化
  • 企業(yè)網(wǎng)站手機版模板免費下載上海關(guān)鍵詞優(yōu)化外包
  • php婚慶網(wǎng)站競價賬戶托管哪家好
  • 大理市住房和城鄉(xiāng)建設(shè)局網(wǎng)站磁力棒
  • wordpress 漏洞 掃描seo網(wǎng)站推廣專員
  • web網(wǎng)站開發(fā)用什么語言網(wǎng)絡(luò)廣告電話
  • 服飾網(wǎng)站模板設(shè)計百度搜索引擎怎么弄
  • 廣西網(wǎng)站建設(shè)運營費用專業(yè)代寫文案的公司
  • html網(wǎng)站開發(fā)工具有哪些互聯(lián)網(wǎng)登錄的網(wǎng)站名
  • 做sns網(wǎng)站需要什么百度熱線電話
  • 網(wǎng)站建設(shè)技術(shù)哪個好seo管理系統(tǒng)
  • qt科技感ui界面sem優(yōu)化軟件哪家好
  • 石家莊做網(wǎng)站價格網(wǎng)站優(yōu)化的關(guān)鍵詞
  • 網(wǎng)站做流量怎么賺錢的培訓(xùn)后的收獲和感想
  • 濟南網(wǎng)站建設(shè)工作室網(wǎng)球排名即時最新排名
  • 有沒有做網(wǎng)站的聯(lián)系方式經(jīng)典營銷案例分析
  • 消費返利系統(tǒng)網(wǎng)站建設(shè)廈門站長優(yōu)化工具
  • 做電商網(wǎng)站注意什么問題seo推廣代運營
  • 建設(shè)信用卡銀行積分商城網(wǎng)站福清網(wǎng)絡(luò)營銷
  • 網(wǎng)站制作難點seo是做什么工作內(nèi)容
  • 網(wǎng)站設(shè)計流程電話站長工具網(wǎng)