国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

C++中的運(yùn)算符重載函數(shù)基礎(chǔ)及其值返回狀態(tài)

2019-11-17 05:26:14
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  運(yùn)算符重載是C++的重要組成部分,它可以讓程序更加的簡(jiǎn)單易懂,簡(jiǎn)單的運(yùn)算符使用可以使復(fù)雜函數(shù)的理解更直觀。

  對(duì)于普通對(duì)象來(lái)說(shuō)我們很自然的會(huì)頻繁使用算數(shù)運(yùn)算符讓他們參與計(jì)算,但是對(duì)于自定義類的對(duì)象來(lái)說(shuō),我們是無(wú)論如何也不能阻止寫出像下面的代碼一樣的程序來(lái)的。

例子如下:

 C++ 代碼 class Test 

    //過(guò)程省略 

 
int main() 

    Test a,c; 
    c=a+a; 
}


  當(dāng)然這樣的代碼是不能夠通過(guò)編譯的,c++對(duì)自定類的算術(shù)運(yùn)算部分保留給了程序員,這也是符合c++靈活特性的。
  在c++中要想實(shí)現(xiàn)這樣的運(yùn)算就必須自定義運(yùn)算符重載函數(shù),讓它來(lái)完整具體工作。
  在這里要提醒讀者的是,自定義類的運(yùn)算符重載函數(shù)也是函數(shù),你重載的一切運(yùn)算符不會(huì)因?yàn)槭悄阕约憾x的就改變其運(yùn)算的優(yōu)先級(jí),自定義運(yùn)算符的運(yùn)算優(yōu)先級(jí)同樣遵循與內(nèi)部運(yùn)算符一樣的順序。
  除此之外,c++也規(guī)定了一些運(yùn)算符不能夠自定義重載,例如.、::等等。 三層交換技術(shù) 交換機(jī)與路由器密碼恢復(fù) 交換機(jī)的選購(gòu) 路由器設(shè)置專題 路由故障處理手冊(cè) 數(shù)字化校園網(wǎng)解決方案 C++中的運(yùn)算符重載函數(shù)基礎(chǔ)及其值返回狀態(tài)

  上表是在C++中答應(yīng)重載的運(yùn)算符總表

  下面我們來(lái)學(xué)習(xí)如何重載運(yùn)算符,運(yùn)算符重載函數(shù)的形式是:

返回類型 Operator 運(yùn)算符符號(hào) (參數(shù)說(shuō)明)
{
//函數(shù)體的內(nèi)部實(shí)現(xiàn)
}

  運(yùn)算符重載函數(shù)的使用主要分為兩種形式,一種是作為類的友元函數(shù)進(jìn)行使用,另一種則是作為類的成員函數(shù)進(jìn)行使用。

下面我們先看一下作為類的友元函數(shù)使用的例子:

 C++ 代碼  
//程序作者:管寧     
//站點(diǎn):www.cndev-lab.com     
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必聞名出處和作者    
 
#include <iostream> 
using namespace std; 
 
class Test 

    public: 
        Test(int a = 0) 
        { 
            Test::a = a; 
        } 
        friend Test operator +(Test&,Test&); 
        friend Test& operator ++(Test&); 
    public: 
        int a; 
}; 
Test operator +(Test& temp1,Test& temp2)//+運(yùn)算符重載函數(shù) 

    //cout<<temp1.a<<""<<temp2.a<<endl;//在這里可以觀察傳遞過(guò)來(lái)的引用對(duì)象的成員分量 
    Test result(temp1.a+temp2.a); 
    return result; 

Test& operator ++(Test& temp)//++運(yùn)算符重載函數(shù) 

    temp.a++; 
    return temp; 

int main() 

    Test a(100); 
    Test c=a+a; 
    cout<<c.a<<endl; 
    c++; 
    cout<<c.a<<endl; 
    system("pause"); 
}


  在例子中,我們對(duì)于自定義類Test來(lái)說(shuō),重載了加運(yùn)算符與自動(dòng)遞增運(yùn)算符,重載的運(yùn)算符完成了同類型對(duì)象的加運(yùn)算和遞增運(yùn)算過(guò)程。

  重載運(yùn)算符函數(shù)返回類型和形式參數(shù)也是根據(jù)需要量進(jìn)行調(diào)整的,下面我們來(lái)看一下修改后的加運(yùn)算符重載函數(shù)。

代碼如下:


 C++ 代碼  
//程序作者:管寧     
//站點(diǎn):www.cndev-lab.com     
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必聞名出處和作者    
 
#include <iostream> 
using namespace std; 
 
class Test 

    public: 
        Test(int a = 0) 
        { 
            Test::a = a; 
        } 
        friend Test operator +(Test&,const int&); 
    public: 
        int a; 
}; 
Test operator +(Test& temp1,const int& temp2)//+運(yùn)算符重載函數(shù) 

    Test result(temp1.a * temp2); 
    return result; 

int main() 

    Test a(100); 
    Test c = a + 10; 
    cout<<c.a<<endl; 
    system("pause"); 
}


  上面修改后的例子中,我們讓重載后的加運(yùn)算符做的事情,事實(shí)上并不是同類型對(duì)象的加運(yùn)算,而是自定義類對(duì)象與內(nèi)置int常量對(duì)象的乘法運(yùn)算。

  值得注重的是,對(duì)于運(yùn)算符重載來(lái)說(shuō),我們并不一定要用它一定要做同類型對(duì)象的加法或者是其它運(yùn)算,運(yùn)算符重載函數(shù)本身就是函數(shù),那么在函數(shù)體內(nèi)部我們是可以做任何事情的,但是從不違反常規(guī)思維的角度來(lái)說(shuō),我們沒有必要讓重載加運(yùn)算的函數(shù)來(lái)做與其重載的符號(hào)意義上完全不相符的工作,所以在使用重載運(yùn)算符脫離原意之前,必須保證有足夠的理由。
  下面我們討論一下作為類成員函數(shù)的運(yùn)算符重載函數(shù)的使用,及其函數(shù)的值返回與引用返回的差別。

  下面我們先看實(shí)例,而后逐步分析。

代碼如下(重要部分做了具體的注解):

 C++ 代碼  
//程序作者:管寧     
//站點(diǎn):www.cndev-lab.com     
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必聞名出處和作者    
 
#include <iostream> 
using namespace std; 
 
class Test 

    public: 
        Test(int a = 0) 
        { 
            Test::a = a; 
        } 
        Test(Test &temp) 
        //運(yùn)算符重載函數(shù)為值返回的時(shí)候會(huì)產(chǎn)生臨時(shí)變量,臨時(shí)變量與局部變量result的復(fù)制會(huì)調(diào)用拷貝構(gòu)造函數(shù),臨時(shí)變量的生命周期是在拷貝構(gòu)造函數(shù)運(yùn)行完成后才結(jié)束,但假如運(yùn)算符重載函數(shù)返回的是引用,那么不會(huì)產(chǎn)生臨時(shí)變量,而局部變量result的生命周期在運(yùn)算符重載函數(shù)退出后立即消失,它的生命周期要比臨時(shí)變量短,所以當(dāng)外部對(duì)象獲取返回值的內(nèi)存地址所存儲(chǔ)的值的時(shí)候,獲得是一個(gè)已經(jīng)失去效果的內(nèi)存地址中的值,在這里的值返回與引用返回的對(duì)比,證實(shí)了臨時(shí)變量的生命周期比局部變量的生命周期稍長(zhǎng)。 
        { 
            cout<<"載入拷貝構(gòu)造函數(shù)"<<""<<temp.a<<endl;//注重這里,假如修改運(yùn)算符重載函數(shù)為返回引用,這里就會(huì)出現(xiàn)異常,temp.a將獲得一個(gè)隨機(jī)值。 
            Test::a = temp.a; 
        } 
        ~Test()//在mian()內(nèi)析構(gòu)的過(guò)程是result局部變量產(chǎn)生的 
        { 
            cout<<"載入析構(gòu)函數(shù)!"<<endl; 
            cin.get(); 
        } 
        Test operator +(Test& temp2)//+運(yùn)算符重載函數(shù) 
        { 
            //cout<<this->a<<endl; 
            Test result(this->a+temp2.a); 
            return result; 
        } 
        Test& operator ++()//++運(yùn)算符重載函數(shù) 
 
        //遞增運(yùn)算符是單目運(yùn)算符,使用返回引用的運(yùn)算符重載函數(shù)道理就在于它需要改變自身。 
        //在前面我們學(xué)習(xí)引用的單元中我們知道,返回引用的函數(shù)是可以作為左值參與運(yùn)算的,這一點(diǎn)也符合單目運(yùn)算符的特點(diǎn)。 
        //假如把++運(yùn)算符重載函數(shù)改成值返回的話,程序中的++(++c)運(yùn)算結(jié)束后輸出c.a,會(huì)發(fā)現(xiàn)對(duì)象c只做了一次遞增運(yùn)算,原因在于,當(dāng)函數(shù)是值返回狀態(tài)的時(shí)候括號(hào)內(nèi)的++c返回的不是c本身而是臨時(shí)變量,用臨時(shí)變量參與括號(hào)外的++運(yùn)算,當(dāng)然c的值也就只改變了一次。 
        { 
            this->a++; 
            return *this; 
        } 
    public: 
        int a; 
}; 
 
int main() 

    Test a(100); 
    Test c=a+a; 
    cout<<c.a<<endl; 
    c++; 
    cout<<c.a<<endl; 
    ++c; 
    cout<<c.a<<endl; 
    ++(++c); 
    cout<<c.a<<endl; 
    system("pause"); 
}

三層交換技術(shù) 交換機(jī)與路由器密碼恢復(fù) 交換機(jī)的選購(gòu) 路由器設(shè)置專題 路由故障處理手冊(cè) 數(shù)字化校園網(wǎng)解決方案
  上例中運(yùn)算符重載函數(shù)以類的成員函數(shù)方式出現(xiàn),細(xì)心的讀者會(huì)發(fā)現(xiàn)加運(yùn)算和遞增運(yùn)算重載函數(shù)少了一個(gè)參數(shù),這是為什么呢?
  因?yàn)楫?dāng)運(yùn)算符重載函數(shù)以類成員函數(shù)身份出現(xiàn)的時(shí)候,C++會(huì)隱藏第一個(gè)參數(shù),轉(zhuǎn)而取代的是一個(gè)this指針。

  接下來(lái)我們具體分析一下運(yùn)算符重載函數(shù)的值返回與引用返回的差別。

  當(dāng)我們把代碼中的加運(yùn)算重載函數(shù)修改成返回引用的時(shí)候:

 C++ 代碼         Test& operator +(Test& temp2)//+運(yùn)算符重載函數(shù)   
        { 
            Test result(this->a+temp2.a);   
            return result;   
        }


  執(zhí)行運(yùn)算符重載函數(shù)返回引用將不產(chǎn)生臨時(shí)變量,外部的Test c=a+a; 將獲得一個(gè)局部的,棧空間內(nèi)存地址位置上的值,而棧空間的特性告訴我們,當(dāng)函數(shù)退出的時(shí)候函數(shù)體中局部對(duì)象的生命周期隨之結(jié)束,所以保存在該地址中的數(shù)據(jù)也將消失,當(dāng)c對(duì)象去獲取存儲(chǔ)在這個(gè)地址中的值的時(shí)候,里面的數(shù)據(jù)已經(jīng)不存在,導(dǎo)致c獲得的是一個(gè)隨機(jī)值,所以作為雙目運(yùn)算的加運(yùn)算符重載函數(shù)是不益采用返回引用方式編寫的,當(dāng)然假如一定要返回引用,我們可以在堆內(nèi)存中動(dòng)態(tài)開辟空間存儲(chǔ)數(shù)據(jù),但是這么做會(huì)導(dǎo)致額外的系統(tǒng)開銷,同時(shí)也會(huì)讓程序更難讀懂。


  對(duì)于遞增運(yùn)算符來(lái)說(shuō),它的意義在于能夠改變自身,返回引用的函數(shù)是可以作為左值參與運(yùn)算的,所以作為單目運(yùn)算符,重載它的函數(shù)采用返回引用的方式編寫是最合適的。

  假如我們修改遞增運(yùn)算符重載函數(shù)為值返回狀態(tài)的時(shí)候,又會(huì)出現(xiàn)什么希奇的現(xiàn)象呢?

代碼如下:

 C++ 代碼         Test operator ++() 
        { 
            return this->a++; 
        }


  表面上是發(fā)現(xiàn)不出什么非凡明顯的問題的,但是在main()函數(shù)中++(++c);的執(zhí)行結(jié)果卻出乎意料,理論上應(yīng)該是204的值,卻只是203,這是為什么呢?
  因?yàn)楫?dāng)函數(shù)是值返回狀態(tài)的時(shí)候括號(hào)內(nèi)的++c返回的不是c本身而是臨時(shí)變量,用臨時(shí)變量參與括號(hào)外的++運(yùn)算,當(dāng)然c的值也就只改變了一次。結(jié)果為203而不是204。


  對(duì)于運(yùn)算符重載函數(shù)來(lái)說(shuō),最后我們還要注重一個(gè)問題,當(dāng)運(yùn)算符重載函數(shù)的形式參數(shù)類型全部為內(nèi)部類型的時(shí)候,將不能重載。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 乐东| 南华县| 象州县| 吉安市| 日土县| 芷江| 广灵县| 安顺市| 文山县| 亳州市| 桑日县| 开化县| 施秉县| 施秉县| 合江县| 乡城县| 莎车县| 科技| 泰安市| 余干县| 枝江市| 瑞昌市| 林口县| 山西省| 锦屏县| 顺平县| 噶尔县| 达拉特旗| 香港| 德阳市| 唐山市| 郴州市| 定日县| 潼关县| 林周县| 辽阳县| 深泽县| 孟州市| 诸城市| 八宿县| 呼伦贝尔市|