看源碼學C++運算子多載

來源:互聯網
上載者:User

“什麼是運算子的重載”與“為什麼要引入運算子多載?”這兩個問題,在這裡都不多說了,百度一下就都OK了

下面說了一下一些比較容易錯的重載,

首先看看模板們是如何聲明重載的

下是iterator 模板中的一段源碼,大家看看它的格式:

iterator 的一段源碼

typedef _Vector_iterator<_Ty, _Alloc> _Myt;reference operator*() const{// return designated objectreturn ((reference)**(_Mybase *)this);}pointer operator->() const{// return pointer to class objectreturn (&**this);}_Myt& operator++(){// preincrement++(*(_Mybase *)this);return (*this);}_Myt operator++(int){// postincrement_Myt _Tmp = *this;++*this;return (_Tmp);}_Myt& operator--(){// predecrement--(*(_Mybase *)this);return (*this);}_Myt operator--(int){// postdecrement_Myt _Tmp = *this;--*this;return (_Tmp);}_Myt& operator+=(difference_type _Off){// increment by integer(*(_Mybase *)this) += _Off;return (*this);}_Myt operator+(difference_type _Off) const{// return this + integer_Myt _Tmp = *this;return (_Tmp += _Off);}_Myt& operator-=(difference_type _Off){// decrement by integerreturn (*this += -_Off);}_Myt operator-(difference_type _Off) const{// return this - integer_Myt _Tmp = *this;return (_Tmp -= _Off);}difference_type operator-(const _Mybase& _Right) const{// return difference of iteratorsreturn (*(_Mybase *)this - _Right);}reference operator[](difference_type _Off) const{// subscriptreturn (*(*this + _Off));}

根據上面的源碼樣本,我們很容易看到:

首碼++(--)與尾碼++(--)

1、a++
       函數返回:temp(臨時變數)
       函數返回是否是const類型:返回是一個拷貝後的臨時變數),不能出現在等號的左邊(臨時變數不能做左值),函數的結果只能做右值,則要返回一個const類型的值
      ++a
       函數返回:*this;
      函數返回是否是const類型:返回原狀態的本身,傳回值可以做左值,即函數的結果可以做左值,則要返回一個非const類型的值
2、前尾碼僅從函數名(operator++)無法區分,只能有參數區分,這裡引入一個虛參數int x,x可以是任意整數。
3、單目運算子的重載:
      重載運算子函數名:operator@(參數表)
      隱式調用形式:obj1@  或 @obj1
      顯式調用形式:
             成員函數:
                    obj1.operator@( )//首碼
                    obj1.operator@(0)//尾碼
             友元函數:
                    operator@(OBJ obj)//首碼
                    operator@(OBJ obj,int x)//尾碼
      執行時,隱式調用形式和顯式調用形式都會調用函數operator@()

給出樣本出下:

#include <iostream>using namespace std;class Point  {  private:  int x; public:  Point(int x1){  x=x1;}  Point& operator++();//成員函數定義自增Point operator++(int x); //尾碼可以返回一個const類型的值//Point& operator--();//成員函數定義自增//Point operator--(int x); //尾碼可以返回一個const類型的值friend Point& operator--(Point& p);//友元函數定義--friend Point operator--(Point& p,int x);//尾碼可以返回一個const類型的值friend ostream& operator<<(ostream&out,const Point& p ){out<<p.x;return out ;}};  Point& Point::operator++()//++obj{x++;return *this;}Point Point::operator++(int x)//obj++{Point temp = *this;this->x++;return temp;}Point& operator--(Point& p)//--obj{p.x--;return p;//首碼形式(--obj)重載的時候沒有虛參,通過引用返回*this 或 自身引用,也就是返回變化之後的數值}Point operator--(Point& p,int x)//obj--{Point temp = p;p.x--;return temp;// 尾碼形式obj--重載的時候有一個int類型的虛參, 返回原狀態的拷貝}int main(){Point a(1);Point b(2);a++;//隱式調用成員函數operator++(0),尾碼運算式++a;//隱式調用成員函數operator++(),首碼運算式b--;//隱式調用友元函數operator--(0),尾碼運算式--b;//隱式調用友元函數operator--(),首碼運算式cout<<a.operator ++(2);//顯式調用成員函數operator ++(2),尾碼運算式cout<<a.operator ++();//顯式調用成員函數operator ++(),首碼運算式cout<<operator --(b,2);//顯式調用友元函數operator --(2),尾碼運算式cout<<operator --(b);//顯式調用友元函數operator --(),首碼運算式 </pre>return 0;}

重載輸入輸出操作符<< >>(另外再強調一下這個)

重載方式:只能使用友元函數重載 且 使用三個引用&
函數名:
       輸出資料流: operator<<(參數表)
       輸入資料流:operator>>(參數表)
參數表:固定(容易出錯啊),兩個參數均用引用&
       輸出資料流: 必須是兩個參數:對輸出資料流ostream& 和 對象
                        第一個運算元cout,定義在檔案iostream中,是標準類類型ostream的對象的引用。
                        如:ostream& cout,const Point& p
       輸入資料流:必須是兩個參數:對輸入資料流ostream& 和 對象
                       第一個運算元是cin,定義在檔案iostream,實際上是標準類類型istream的對象的引用
                       如:instream& cin,const Point& p
函數調用:
       輸出資料流: 顯式調用:cout<<對象
                        隱式調用: operator<<(cout,對象)
       輸入資料流:顯式調用:cin>>對象
                        隱式調用: operator>>(cin,對象)
傳回型別:傳回型別固定 + 使用返回函數引用(滿足連續輸出)
       輸出資料流: 返回ostream&
                        如:ostream& operator<<(ostream& cout,const Point& p)
       輸入資料流:返回:istream&
                        如:istream& operator>>(istream& cin,Point& p)
注意:為什麼輸入輸出操作符的重載必須使用友元函數?
因為:成員函數要求是有對象調用,則第一個參數必須是類的對象,但是<<和>>第一個參數是流的對象引用。故,不能使用成員函數

範例程式碼如下:

class ABC{int data ;public:ABC(int d):data(90){}friend ostream&operator<<(ostream&out,const ABC &o) ;friend istream& operator >>(istream & in, ABC &i);};ostream &operator<<(ostream&out,const ABC &o){out<<o.data;return out ;}istream &operator>>(istream& in, ABC &i){in>>i.data ;return in;}

部分內容參考:http://blog.csdn.net/insistgogo/article/details/6626952

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.