欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++重載的奧義之運(yùn)算符重載詳解

 更新時間:2023年04月18日 10:40:43   作者:Sharemaker  
函數(shù)的重載是指利用相同的函數(shù)名設(shè)計一系列功能相近,但是功能細(xì)節(jié)不一樣的函數(shù)接口;因此運(yùn)算符重載也是指對于同一個運(yùn)算符來說,它可以用于實(shí)現(xiàn)不同的功能。下面就一起來理解下運(yùn)算符重載的應(yīng)用吧

0、引言

重載,顧名思義從字面上理解就是重復(fù)裝載,打一個不恰當(dāng)?shù)谋确?,你可以用一個籃子裝蔬菜,也可以裝水果或者其它,使用的是同一個籃子,但是可以用籃子重復(fù)裝載的東西不一樣。

正如在之前的文章《重載的奧義之函數(shù)重載》中介紹的類似,函數(shù)的重載是指利用相同的函數(shù)名設(shè)計一系列功能相近,但是功能細(xì)節(jié)不一樣的函數(shù)接口;因此運(yùn)算符重載也是指對于同一個運(yùn)算符來說,它可以用于實(shí)現(xiàn)不同的功能。下面就一起來理解下運(yùn)算符重載的應(yīng)用。

1、運(yùn)算符重載定義

正常來說,我們一般使用的運(yùn)算符是對基本的數(shù)據(jù)類型進(jìn)行操作,但是在C++中有了對象,導(dǎo)致對象無法通過運(yùn)算符進(jìn)行運(yùn)算,故引入了運(yùn)算符重載即需要重新的定義這些運(yùn)算符,賦予已有運(yùn)算符新的功能,使它能夠用于特定類型執(zhí)行特定的操作。運(yùn)算符重載的實(shí)質(zhì)是函數(shù)重載,它提供了C++的可擴(kuò)展性。

運(yùn)算符重載是通過創(chuàng)建運(yùn)算符函數(shù)實(shí)現(xiàn)的,運(yùn)算符函數(shù)定義了重載的運(yùn)算符將要進(jìn)行的操作。運(yùn)算符函數(shù)的定義與其他函數(shù)的定義類似,唯一的區(qū)別是運(yùn)算符函數(shù)的函數(shù)名是由關(guān)鍵字operator和其后要重載的運(yùn)算符符號構(gòu)成的。運(yùn)算符函數(shù)定義的一般格式如下:

<返回類型說明符> operator <運(yùn)算符符號>(<參數(shù)表>)
{
      <函數(shù)體>
}

其中,“返回類型說明符”指出重載運(yùn)算符的返回值類型,operator是定義運(yùn)算符重載函數(shù)的關(guān)鍵字,“運(yùn)算符符號”指出要重載的運(yùn)算符名字,是C++中可重載的運(yùn)算符,比如要重載加法運(yùn)算符,這里直接寫“+”即可,“參數(shù)表”指出重載運(yùn)算符所需要的參數(shù)及其類型??梢钥闯觯\(yùn)算符重載是一種形式C++多態(tài)的體現(xiàn)。

例如,使用“+”將兩個對象相加,編譯器將根據(jù)操作數(shù)的數(shù)目和類型決定使用哪種加法定義,這樣可以讓代碼看起來更加自然。

//正常情況下兩個數(shù)組的數(shù)相加
for(int i= 0; i<10; i++)
    c[i] = a[i] + b[i];
//可以通過定義一個數(shù)組的類,重載“+”運(yùn)算符后
//隱藏了內(nèi)部機(jī)制,并強(qiáng)調(diào)了實(shí)質(zhì)
arry operator+(arry p,arry q)
{
   arry t;
    for(int i= 0; i<10; i++)  //c = a + b;
    {
      t.a[i]=p.a[i]+q.a[i];
    }
    return t;
}

運(yùn)算符重載就是對已有的運(yùn)算符重新進(jìn)行定義,賦予其另一種功能,以達(dá)到適應(yīng)不同的數(shù)據(jù)類型。運(yùn)算符重載不能改變它本來的寓意(也就是加法不能變更為減法),運(yùn)算符重載只是一種 “語法上的方便” ,它只是一種函數(shù)調(diào)用的方式。

2、作為成員函數(shù)進(jìn)行重載

我們就以“+”運(yùn)算符重載舉例:

#include <iostream>
using namespace std;
class addfloat
{
public:
    addfloat(float p);
    //聲明運(yùn)算符重載
    addfloat operator+(const addfloat &A) const;
    void show() const;
private:
    float m_p;
};
addfloat::addfloat(float p)
{
    m_p = p;
}
//作為類的成員函數(shù)實(shí)現(xiàn)運(yùn)算符重載
addfloat addfloat::operator+(const addfloat &A) const
{
    addfloat B;
    B.m_p = this->m_p + A.m_p;
    return B;
}
void addfloat::show() const
{
    cout<<"輸出結(jié)果是"<<m_p<<endl;
}


int main()
{
    addfloat m(5.1);
    addfloat n(1.5);
    addfloat t;
    t = m + n; //兩個addfloat類對象相加:t = m.operator+(n);
    t.show();
    return 0;
}

運(yùn)行結(jié)果為:

輸出結(jié)果是6.6

從上面的例子可以看出,在addfloat類中對“+”運(yùn)算符進(jìn)行了重載 ,重載后可以對該類的對象進(jìn)行加法運(yùn)算。當(dāng)運(yùn)行 t = m + n時,編譯器檢測到“+”左邊的m(“+”具有左結(jié)合性,所以先檢測左邊)是一個 addfloat類對象,就會調(diào)用成員函數(shù) operator+(),將表達(dá)式轉(zhuǎn)換成如下格式:

t = m.operator + (n);

表達(dá)式中m作為調(diào)用函數(shù)的對象,n作為函數(shù)的實(shí)參。

3、作為全局函數(shù)進(jìn)行重載

對于之前的例子:t = m + n,m和n是作為addfloat類的對象進(jìn)行相加的,使用成員函數(shù) operator+()轉(zhuǎn)換為了t = m.operator+(n),如果n不是類的對象,而是一個常數(shù),例如:

t = m + 5.2;那么可以轉(zhuǎn)換t = m.operator+(5.2);

但是如果m是一個常數(shù)時,即:t = 5.2 + n;則t = (5.2).operator + (n)這種轉(zhuǎn)換是不允許的,編譯器會報錯,因?yàn)?.2不能作為類的對象調(diào)用運(yùn)算符重載operator+()函數(shù)。

這種場景下針對“+”這種運(yùn)算符作為類的成員函數(shù)進(jìn)行重載是不可以的。運(yùn)算符重載不僅僅可以通過類的成員函數(shù)來實(shí)現(xiàn),也可以通過全局函數(shù)來實(shí)現(xiàn)。

我們需要將運(yùn)算符重載的全局函數(shù)聲明為友元函數(shù),因?yàn)榇蠖鄶?shù)時候重載運(yùn)算符要訪問類的私有數(shù)據(jù),(當(dāng)然也可以設(shè)置為非友元非類的成員函數(shù),但是非友元又不是類的成員函數(shù),是沒有辦法直接訪問類的私有數(shù)據(jù)的),如果不聲明為類的友元函數(shù),而是通過在此函數(shù)中調(diào)用類的公有函數(shù)來訪問私有數(shù)據(jù)會降低性能。所以一般都會設(shè)置為類的友元函數(shù),這樣我們就可以在此非成員函數(shù)中訪問類中的數(shù)據(jù)了。

#include <iostream>
using namespace std;
class addfloat
{
public:
    addfloat(float p);
    //聲明為友元函數(shù)
    friend addfloat operator+(const addfloat &A, const addfloat &B);
    void show() const;
private:
    float m_p;
};
addfloat::addfloat(float p)
{
    m_p = p;
}

void addfloat::show() const
{
    cout<<"輸出結(jié)果是"<<m_p<<endl;
}

//作為全局函數(shù)進(jìn)行重載
addfloat operator+(const addfloat &A, const addfloat &B)
{
    addfloat C;
    C.m_p = A.m_p + B.m_p;
    return C;
}

int main()
{
    addfloat m(5.1);
    addfloat n(1.5);
    addfloat t;
    t = m + n; //兩個addfloat類對象相加:t = m.operator+(n);
    t.show();
    return 0;
}

由上述程序可以看出,運(yùn)算符重載函數(shù)operator+()不是 addfloat類的成員函數(shù),但是卻用到了 addfloat類的 private 成員變量m_p,所以需要在 addfloat類中將operator+()函數(shù)聲明為友元函數(shù)。

當(dāng)運(yùn)行t = m + n時,編譯器檢測到“+”兩邊都是addfloat類的對象,就會轉(zhuǎn)換為類似下面的函數(shù)調(diào)用:

t = operator + (m, n);

因此,m和n都可以看作是函數(shù)的實(shí)參:

t = m + 5.2轉(zhuǎn)換為 t = operator + (m, 5.2);

t = 5.2 + n轉(zhuǎn)換為 t = operator + (5.2, n);

以全局函數(shù)的形式重載“+”,是為了保證“+”運(yùn)算符的操作數(shù)能夠被對稱的處理;換句話說,常數(shù)在“+”左邊和右邊都是正確的;

因此,運(yùn)算符左右兩邊都有操作對象時,且這兩個操作對象可以互換,最好可以使用全局函數(shù)的形式重載,例如:+、-、*、/、==、!= ,這些符合運(yùn)算符兩邊有操作對象的運(yùn)算符。

4、運(yùn)算符重載的一些規(guī)則

(1)可以重載的運(yùn)算符?

(2)不可以重載的運(yùn)算符

.         (成員訪問運(yùn)算符)

.*       (成員指針訪問運(yùn)算符)

::        (域運(yùn)算符)

sizeof (長度運(yùn)算符)

?:        (條件運(yùn)算符)

(3) 只能以成員函數(shù)的形式重載的運(yùn)算符(與 this關(guān)聯(lián)太多)

=         (賦值運(yùn)算符)

()         (函數(shù)調(diào)用運(yùn)算符)

[]         (下標(biāo)運(yùn)算符)

->       (成員訪問運(yùn)算符)

(4)只能以全局函數(shù)重載的運(yùn)算符

<<      (左移運(yùn)算符)

>>      (右移運(yùn)算符)

(5)運(yùn)算符重載函數(shù)既可以作為類的成員函數(shù),也可以作為全局函數(shù)。友元函數(shù)運(yùn)算符重載函數(shù)與成員運(yùn)算符重載函數(shù)的區(qū)別是:友元函數(shù)沒有this指針,而成員函數(shù)有,因此,在兩個操作數(shù)的重載中友元函數(shù)有兩個參數(shù),而成員函數(shù)只有一個。

(6)有一部分運(yùn)算符重載既可以是成員函數(shù)也可以是全局函數(shù),雖然沒有一個必然的、不可抗拒的理由選擇成員函數(shù),但我們應(yīng)該優(yōu)先考慮成員函數(shù),這樣更符合運(yùn)算符重載的初衷。

(7)對于復(fù)合的賦值運(yùn)算符如 +=、-=、*=、/=、&=、!=、~=、%=、>>=、<<= 建議重載為成員函數(shù);

單目運(yùn)算符最好重載為成員函數(shù);

對于其它運(yùn)算符,建議重載為全局函數(shù)。

(8)使用運(yùn)算符不能違反運(yùn)算符原來的語法規(guī)則,原來有幾個操作數(shù)、操作數(shù)在左邊還是在右邊,這些都不會改變。算符重載函數(shù)不能有默認(rèn)的參數(shù),否則就改變了運(yùn)算符操作數(shù)的個數(shù)。

(9)運(yùn)算符的優(yōu)先級不能被重載改變。然而,圓括號能夠強(qiáng)制改變表達(dá)式中重載運(yùn)算符的求值順序。

(10)運(yùn)算符的結(jié)合性不能被重載改變。如果一個運(yùn)算符的結(jié)合性是從左向右,那么,它的所有重載的版本的結(jié)合性依然是從左向右

(11)不能創(chuàng)造新的運(yùn)算符,即只能重載現(xiàn)有的運(yùn)算符。例如不能定義operator** (···)來表示求冪。

(12)重載的運(yùn)算符必須和用戶定義的對象一起使用,運(yùn)算符參數(shù)(操作的對象)中至少應(yīng)有一個是類對象(或類對象的引用)。

以上就是C++重載的奧義之運(yùn)算符重載詳解的詳細(xì)內(nèi)容,更多關(guān)于C++運(yùn)算符重載的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++ const關(guān)鍵字分析詳解

    C++ const關(guān)鍵字分析詳解

    C++中的const關(guān)鍵字的用法非常靈活,而使用const將大大改善程序的健壯性。這篇文章主要介紹了C/C++ 中const關(guān)鍵字的用法,需要的朋友可以參考下
    2021-08-08
  • 詳解在C++中顯式默認(rèn)設(shè)置的函數(shù)和已刪除的函數(shù)的方法

    詳解在C++中顯式默認(rèn)設(shè)置的函數(shù)和已刪除的函數(shù)的方法

    這篇文章主要介紹了在C++中顯式默認(rèn)設(shè)置的函數(shù)和已刪除的函數(shù)的方法,文中講到了C++11標(biāo)準(zhǔn)中的新特性,需要的朋友可以參考下
    2016-01-01
  • C語言簡明講解歸并排序的應(yīng)用

    C語言簡明講解歸并排序的應(yīng)用

    這篇文章主要介紹了 c語言排序之歸并排序,歸并就是把兩個或多個序列合并,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • C++短路求值(邏輯與、邏輯或)實(shí)例

    C++短路求值(邏輯與、邏輯或)實(shí)例

    這篇文章主要介紹了C++短路求值(邏輯與、邏輯或)實(shí)例,以實(shí)例形式講述了邏輯或的短路與邏輯與的短路及相應(yīng)的應(yīng)用實(shí)例,需要的朋友可以參考下
    2014-10-10
  • C++精要分析右值引用與完美轉(zhuǎn)發(fā)的應(yīng)用

    C++精要分析右值引用與完美轉(zhuǎn)發(fā)的應(yīng)用

    C++11標(biāo)準(zhǔn)為C++引入右值引用語法的同時,還解決了一個短板,即使用簡單的方式即可在函數(shù)模板中實(shí)現(xiàn)參數(shù)的完美轉(zhuǎn)發(fā)。那么,什么是完美轉(zhuǎn)發(fā)?它為什么是C++98/03 標(biāo)準(zhǔn)存在的一個短板?C++11標(biāo)準(zhǔn)又是如何為C++彌補(bǔ)這一短板的?別急,本節(jié)將就這些問題給讀者做一一講解
    2022-05-05
  • C++構(gòu)造函數(shù)詳解

    C++構(gòu)造函數(shù)詳解

    這篇文章主要介紹了C++構(gòu)造函數(shù)詳解,上一篇文章我們介紹了定義了類,在使用之前,往往還需要對類進(jìn)行初始化。這篇介紹的就是對類進(jìn)行初始化的方法,需要的朋友可以參考一下
    2022-01-01
  • C語言掃雷游戲的實(shí)現(xiàn)

    C語言掃雷游戲的實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了C語言掃雷游戲的實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C++利用easyx圖形庫實(shí)現(xiàn)創(chuàng)意天天酷跑小游戲

    C++利用easyx圖形庫實(shí)現(xiàn)創(chuàng)意天天酷跑小游戲

    這篇文章主要為大家詳細(xì)介紹了C++如何利用easyx圖形庫實(shí)現(xiàn)創(chuàng)意小游戲——天天酷跑,文中的示例代碼講解詳細(xì),快跟隨小編一起了解一下吧
    2023-03-03
  • C語言實(shí)現(xiàn)電子時鐘程序

    C語言實(shí)現(xiàn)電子時鐘程序

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)電子時鐘程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • CLOSE_WAIT狀態(tài)解決方案

    CLOSE_WAIT狀態(tài)解決方案

    這篇文章主要介紹了CLOSE_WAIT狀態(tài)解決方案,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評論