挑戰(zhàn)30天C++入門(mén)極限:對(duì)C++遞增(增量)運(yùn)算符重載的思考

字號(hào):

在前面的章節(jié)中我們已經(jīng)接觸過(guò)遞增運(yùn)算符的重載,那時(shí)候我們并沒(méi)有區(qū)分前遞增與后遞增的差別,在通常情況下我們是分別不出++a與a++的差別的,但的確他們直接是存在明顯差別的。
    先看如下代碼:
    C++ 代碼 #include
    using namespace std;
    int main()
    {
     int a=0;
     ++(++a);//正確,(++a)返回的是左值
     (a++)++;//錯(cuò)誤,(a++)返回的不是左值
     system("pause");
    }
    代碼中(a++)++編譯出錯(cuò)誤,返回“++”需要左值的錯(cuò)誤,這正是前遞增與后遞增的差別導(dǎo)致的,那么又是為什么呢?
    原因主要是由C++對(duì)遞增(增量)運(yùn)算符的定義引發(fā)的。
    他們之間的差別主要為以下兩點(diǎn):
    1.運(yùn)算過(guò)程中,先將對(duì)象進(jìn)行遞增修改,而后返回該對(duì)象(其實(shí)就是對(duì)象的引用)的叫前遞增(增量)運(yùn)算。在運(yùn)算符重載函數(shù)中采用返回對(duì)象引用的方式編寫(xiě)。
    2.運(yùn)算過(guò)程中,先返回原有對(duì)象的值,而后進(jìn)行對(duì)象遞增運(yùn)算的叫后遞增(增量)運(yùn)算。在運(yùn)算符重載函數(shù)中采用值返回的方式編寫(xiě)(這也正是前面(a++)++出錯(cuò)誤的原因,(a++)返回的不是引用,不能當(dāng)作左值繼續(xù)參加擴(kuò)號(hào)外部的++運(yùn)算),重載函數(shù)的內(nèi)部實(shí)現(xiàn)必須創(chuàng)建一個(gè)用于臨時(shí)存儲(chǔ)原有對(duì)象值的對(duì)象,函數(shù)返回的時(shí)候就是返回該臨時(shí)對(duì)象。
    那么在編寫(xiě)運(yùn)算符重載函數(shù)的時(shí)候我們?cè)撊绾螀^(qū)分前遞增運(yùn)算符重載函數(shù)與后遞增運(yùn)算符重載函數(shù)呢?
    方法就是:在后遞增運(yùn)算符重載函數(shù)的參數(shù)中多加如一個(gè)int標(biāo)識(shí),標(biāo)記為后遞增運(yùn)算符重載函數(shù)。
    具體見(jiàn)如下實(shí)例(例一為非成員方式,例二為成員方式):
    C++ 代碼 //例一
    //程序作者:管寧
    //站點(diǎn):www.cndev-lab.com
    //所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必出處和作者
    #include
    using namespace std;
    class Test
    {
     public:
     Test(int a=0)
     {
     Test::a = a;
     }
     friend Test& operator ++ (Test&);
     friend Test operator ++ (Test&,int);
     public:
     int a;
    };
    Test& operator ++ (Test &temp)//前遞增
    {
     temp.a++;
     return temp;
    }
    Test operator ++ (Test &temp,int)//后遞增,int在這里只起到區(qū)分作用,事實(shí)上并沒(méi)有實(shí)際作用
    {
     Test rtemp(temp);//這里會(huì)調(diào)用拷貝構(gòu)造函數(shù)進(jìn)行對(duì)象的復(fù)制工作
     temp.a++;
     return rtemp;
    }
    int main()
    {
     Test a(100);
     ++(++a);
     cout< cout<<"觀察后遞增情況下臨時(shí)存儲(chǔ)對(duì)象的值狀態(tài):"<<(a++).a<     cout< (a++)++;
     cout< system("pause");
    }
    C++ 代碼 //例二
    //程序作者:管寧
    //站點(diǎn):www.cndev-lab.com
    //所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必出處和作者
    #include
    using namespace std;
    class Test
    {
     public:
     Test(int a=0)
     {
     Test::a = a;
     }
     Test& operator ++ ();
     Test operator ++ (int);
     public:
     int a;
    };
    Test& Test::operator ++ ()//前遞增
    {
     this->a++;
     return *this;
    }
    Test Test::operator ++ (int)//后遞增
    {
     Test rtemp(*this);//這里會(huì)調(diào)用拷貝構(gòu)造函數(shù)進(jìn)行對(duì)象的復(fù)制工作
     this->a++;
     return rtemp;
    }
    int main()
    {
     Test a(100);
     ++(++a);
     cout< cout<<"觀察后遞增情況下臨時(shí)存儲(chǔ)對(duì)象的值狀態(tài):"<<(a++).a<     cout< (a++)++;
     cout< system("pause");
    }
    通過(guò)對(duì)前后遞增運(yùn)算的分析,我們可以進(jìn)一步可以了解到,對(duì)于相同情況的單目運(yùn)算符重載我們都必須做好這些區(qū)別工作,保證重載后的運(yùn)算符符合要求。