程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++_運算符重載 總結,運算符重載總結

C++_運算符重載 總結,運算符重載總結

編輯:C++入門知識

C++_運算符重載 總結,運算符重載總結


什麼是運算符的重載?

         運算符與類結合,產生新的含義。 

為什麼要引入運算符重載?

         作用:為了實現類的多態性(多態是指一個函數名有多種含義)

怎麼實現運算符的重載?

方式:類的成員函數 或 友元函數(類外的普通函數)

規則:不能重載的運算符有 .  和 .* 和 ?: 和 ::  和 sizeof

友元函數和成員函數的使用場合:一般情況下,建議一元運算符使用成員函數,二元運算符使用友元函數

        1、運算符的操作需要修改類對象的狀態,則使用成員函數。如需要做左值操作數的運算符(如=,+=,++)

        2、運算時,有數和對象的混合運算時,必須使用友元

        3、二元運算符中,第一個操作數為非對象時,必須使用友元函數。如輸入輸出運算符<<和>>

具體規則如下:

運算符 建議使用 所有一元運算符 成員函數 = ( ) [ ]  -> 必須是成員函數 += -= /= *= ^= &= != %= >>= <<= , 似乎帶等號的都在這裡了 成員函數 所有其它二元運算符, 例如: –,+,*,/ 友元函數 << >> 必須是友元函數

 

2. 參數和返回值

     當參數不會被改變,一般按const引用來傳遞(若是使用成員函數重載,函數也為const).

     對於返回數值的決定:

     1) 如果返回值可能出現在=號左邊, 則只能作為左值, 返回非const引用。

     2) 如果返回值只能出現在=號右邊, 則只需作為右值, 返回const型引用或者const型值。

     3) 如果返回值既可能出現在=號左邊或者右邊, 則其返回值須作為左值, 返回非const引用。

運算符重載舉例:

+和 -運算符的重載:

class Point  
{  
private:  
    int x; 
public:  
    Point(int x1)
    {      x=x1;}  
    Point(Point& p)   
    {      x=p.x;}
    const Point operator+(const Point& p);//使用成員函數重載加號運算符
    friend const Point operator-(const Point& p1,const Point& p2);//使用友元函數重載減號運算符
};  

const Point Point::operator+(const Point& p)
{
    return Point(x+p.x);
}

Point const operator-(const Point& p1,const Point& p2)
{
    return Point(p1.x-p2.x);
}

調用:

Point a(1);  
Point b(2);
a+b;  //正確,調用成員函數
a-b;  //正確,調用友元函數
a+1;  //正確,先調用類型轉換函數,把1變成對象,之後調用成員函數
a-1;  //正確,先調用類型轉換函數,把1變成對象,之後調用友元函數
1+a;  //錯誤,調用成員函數時,第一個操作數必須是對象,因為第一個操作數還有調用成員函數的功能
1-a;  //正確,先類型轉換 後調用友元函數

總結:

1、由於+ -都是出現在=號的右邊,如c=a+b,即會返回一個右值,可以返回const型值
2、後幾個表達式討論的就是,數和對象混合運算符的情況,一般出現這種情況,常使用友元函數

3、雙目運算符的重載:

      重載運算符函數名:operator@(參數表)

      隱式調用形式:obj1+obj2

      顯式調用形式:obj1.operator+(OBJ obj2)---成員函數

                                  operator+(OBJ obj1,OBJ obj2)---友元函數

      執行時,隱式調用形式和顯式調用形式都會調用函數operator+()

++和--運算符的重載:

class Point  
{  
private:  
    int x; 
public:  
    Point(int x1)
    {      x=x1;}  
    Point operator++();//成員函數定義自增
    const Point operator++(int x); //後綴可以返回一個const類型的值
    friend Point operator--(Point& p);//友元函數定義--
    friend const Point operator--(Point& p,int x);//後綴可以返回一個const類型的值
};  

Point Point::operator++()//++obj
{
    x++;
    return *this;
}
const Point Point::operator++(int x)//obj++
{
    Point temp = *this;
    this->x++;
    return temp;
}
Point operator--(Point& p)//--obj
{
    p.x--;
    return p;
         //前綴形式(--obj)重載的時候沒有虛參,通過引用返回*this 或 自身引用,也就是返回變化之後的數值
}
const Point operator--(Point& p,int x)//obj--
{
    Point temp = p;
    p.x--;
    return temp;
         // 後綴形式obj--重載的時候有一個int類型的虛參, 返回原狀態的拷貝
}

函數調用:

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>

總結:

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@()

 重載下標運算符[ ]

class Point  
{  
private:  
    int x[5]; 
public:  
    Point()
    {
        for (int i=0;i<5;i++)
        {
            x[i]=i;
        }
    } 
    int& operator[](int y);
};  
int& Point::operator[](int y)
{
    static int t=0;
    if (y<5)
    {
        return x[y];
    }
    else
    {
        cout<<"下標出界";
        return t;
    }    
}

調用:

Point a;
for (int i=0;i<10;i++)
{
         cout<<a[i]<<endl;//無論i下標是否越界,每當使用a[i]時,都會調用[]的重載
}
a[0]=10;

重載下標運算符[ ]的目的:

          1、對象[x]  類似於 數組名[x],更加符合習慣

          2、可以對下標越界作出判斷

語法:

        重載方式:只能使用成員函數重載

        函數名:operator[ ](參數表)

        參數表:一個參數,且僅有一個參數,該參數設定了下標值,通常為整型,但是也可以為字符串( 看成下標)。

        函數調用:顯式調用:Obj[arg]-對象[下標]

                              隱式調用:obj.operator[ ](arg)  

        返回類型:

               1、返回函數引用 + 返回成員的實際類型(由程序員根據函數體定義)

               2、因為返回值可以做左值和右值,應該不使用返回值為const類型

                     但是,為了能訪問const對象,下標運算符重載有非const和const兩個版本。(待定寫)

 如:int&  Point::operator[](int y)//為什麼使用返回引用:返回的值可以做左值,也可以做右值,則必須使用返回引用

 重載運算符( )

class Point  
{  
private:  
    int x; 
public:  
    Point(int x1)
    {      x=x1;}  
    const int operator()(const Point& p);
};  

const int Point::operator()(const Point& p)
{
    return (x+p.x);
}

調用:

調用:
Point a(1);
Point b(2);
cout<<a(b);

重載運算符( )的目的:

          1、對象( )  類似於 函數名(x),更加符合習慣

語法:

        重載方式:只能使用成員函數重載

        重載後還可以繼續重載

        函數名:operator( )(參數表)

        參數表:參數隨意,具體根據實際情況而定。

        函數調用:顯式調用:Obj(x)

                            隱式調用:obj.operator( )(x)  

        返回類型:

               1、返回成員的實際類型隨意,具體由程序員根據函數體定義

               2、因為返回值只能做右值,只讀,應該使用返回值為const類型


重載輸入輸出操作符<< >>

class Point  
{  
private:  
    int x; 
public:  
    Point(int x1)
    {      x=x1;} 
    friend ostream& operator<<(ostream& cout,const Point& p);//使用友元函數重載<<輸出運算符
    friend istream& operator>>(istream& cin,Point& p);//使用友元函數重載>>輸出運算符
};  
ostream& operator<<(ostream& cout,const Point& p)
{
    cout<<p.x<<endl;
    return cout;
}
istream& operator>>(istream& cin,Point& p)
{
    cin>>p.x;
    return cin;
}
調用:
Point a(1);
Point b(2);
cin>>a>>b;
cout<<a<<b<<endl;    

語法:

重載方式:只能使用友元函數重載 且 使用三個引用&

函數名:

       輸出流: 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)

注意:為什麼輸入輸出操作符的重載必須使用友元函數?

因為:成員函數要求是有對象調用,則第一個參數必須是類的對象,但是<<和>>第一個參數是流的對象引用。

故,不能使用成員函數。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved