C++運算符重載——重載一元運算符


0、重載一元操作符的方法

一元運算符即只需要一個操作用的運算符,如取地址運算符(&)、復數(-)、自減(--)、自加(++)等。

運算符重載可以分為3種方式:類的非靜態成員函數、類的友元函數、普通函數。

例如有 1 個操作數 a,一元運算符 ? (表示一個一元運算符),a? 或者?a 的操作會被解釋為下面2種形式之一 

//a? or ?a
a.operator?();    //類的非靜態成員函數
operator?(a);    //友元函數 和 普通函數

 

第一種形式是運算符被重載為類的非靜態成員函數,沒有參數。

這種方式要求操作數(即a)必須是一個對象,operator?是這個對象的非靜態成員函數,

第二種形式是運算符被重載為類的友元函數 或 普通函數,有1個參數。

重載為 類的友元函數 和 普通函數的區別是 類的友元函數可以直接訪問類的私有成員,而普通函數不可以。

 

1、重載++、--(前置 和 后置)

自增運算符(++)和 自減運算符(--)都有 前置 和 后置 2中情況。

C++中為了區分前置和后置規定:前置重載與普通運算符重載一致,后置重載需要在參數列表中加入一個無用的參數。

++/-- 的3種重載方式如下: 前置的情況可以返回類的引用,后置的情況只能返回臨時對象。

//類的非靜態成員函數
class X
{
    X& operator++(){...}          //前置++
    X  operator++(int){...}       //后置++
   
    X& operator--(){...}         //前置--     
    X  operator--(int){...}      //后置--
}
/*-----------------------------------------------------*/
//類的友元函數
class X
{
    friend X& operator++(X& ref){...}      //前置++
    friend X  operator++(X& ref, int){...} //后置++

    friend X& operator--(X& ref){...}       //前置--
    friend X  operator--(X& ref, int){...}  //后置--  
}
/*-----------------------------------------------------*/
//普通函數
class X
{
...        
}
X& operator++(X& ref){...}         //前置++
X  operator++(X& ref, int){...}    //后置++

X& operator--(X& ref){...}         //前置--
X  operator--(X& ref, int){...}    //后置--

 

 

下例中有3個Counter類 CounterA、CounterB 和CounterC,3個類都重載了前置++、-- 和后置++、--。

其中CounterA使用類的非靜態成員函數方式重載,CounterB使用類的友元函數方式重載,CounterC使用普通函數方式重載

#include <iostream>
using namespace std;

class CounterA
{
public:
    //默認構造函數(Default constructor)
    CounterA(){cout<<"Default Constructor"<<endl;}
    //帶參數的構造函數(The constructor with parameters)
    CounterA(int m):n(m){cout<<"Parameter Constructor"<<endl;}
    //拷貝構造函數(Copy constructor)
    CounterA(const CounterA& ref){n = ref.n; cout<<"Copy Constructor"<<endl;}
    //析構函數(destructor)
    ~CounterA(){cout<<"Destructor"<<endl;}


    //重載運算符 ++(前置)
    const CounterA& operator++(){++n; return *this;}
    //重載運算符 ++(后置)
    const CounterA operator++(int dump){CounterA Tmp(*this);++n; return Tmp;}
    //重載運算符 --(前置)
    const CounterA& operator--(){--n; return *this;}
    //重載運算符 --(后置)
    const CounterA operator--(int dump){CounterA Tmp(*this);--n; return Tmp;}

    //輸出用函數
    void display(void){cout<<"n = " << n << endl;}
    //GetData
    int GetVal(void){return n;}

private:
    int n;
};

class CounterB
{
public:
    //默認構造函數(Default constructor)
    CounterB(){cout<<"Default Constructor"<<endl;}
    //帶參數的構造函數(The constructor with parameters)
    CounterB(int m):n(m){cout<<"Parameter Constructor"<<endl;}
    //拷貝構造函數(Copy constructor)
    CounterB(const CounterB& ref){n = ref.n; cout<<"Copy Constructor"<<endl;}
    //析構函數(destructor)
    ~CounterB(){cout<<"Destructor"<<endl;}

    //重載運算符 ++(前置)
    friend const CounterB& operator++(CounterB& ref){ref.n += 1;return ref;}
    //重載運算符 ++(后置)
    friend const CounterB operator++(CounterB& ref, int dump){CounterB Tmp(ref);ref.n += 1; return Tmp;}
    //重載運算符 --(前置)
    friend const CounterB& operator--(CounterB& ref){ref.n -= 1;return ref;}
    //重載運算符 --(后置)
    friend const CounterB operator--(CounterB& ref, int dump){CounterB Tmp(ref);ref.n -= 1; return Tmp;}

    //輸出用函數
    void display(void){cout<<"n = " << n << endl;}
    //GetData
    int GetVal(void){return n;}
    //SetData
    void SetVal(int val){n = val;}

private:
    int n;
};

class CounterC
{
public:
    //默認構造函數(Default constructor)
    CounterC(){cout<<"Default Constructor"<<endl;}
    //帶參數的構造函數(The constructor with parameters)
    CounterC(int m):n(m){cout<<"Parameter Constructor"<<endl;}
    //拷貝構造函數(Copy constructor)
    CounterC(const CounterC& ref){n = ref.n; cout<<"Copy Constructor"<<endl;}
    //析構函數(destructor)
    ~CounterC(){cout<<"Destructor"<<endl;}


    //輸出用函數
    void display(void){cout<<"n = " << n << endl;}
    //GetData
    int GetVal(void){return n;}
    //SetData
    void SetVal(int val){n = val;}

private:
    int n;
};
//重載運算符 ++(前置)
const CounterC& operator++(CounterC& ref){ref.SetVal(ref.GetVal()+1);return ref;}
//重載運算符 ++(后置)
const CounterC operator++(CounterC& ref, int dump){CounterC Tmp(ref);ref.SetVal(ref.GetVal()+1); return Tmp;}
//重載運算符 --(前置)
const CounterC& operator--(CounterC& ref){ref.SetVal(ref.GetVal()-1);return ref;}
//重載運算符 --(后置)
const CounterC operator--(CounterC& ref, int dump){CounterC Tmp(ref);ref.SetVal(ref.GetVal()-1); return Tmp;}


int main(void)
{
    CounterA cp1(5);cp1.display();
    ++cp1;cp1.display();
    --cp1;cp1.display();
    CounterA cp2(cp1++);cp2.display();
    CounterA cp3(cp1--);cp3.display();

    CounterB cp4(5);cp4.display();
    ++cp4;cp4.display();
    --cp4;cp4.display();
    CounterB cp5(cp4++);cp5.display();
    CounterB cp6(cp4--);cp6.display();

    CounterC cp7(5);cp7.display();
    ++cp7;cp7.display();
    --cp7;cp7.display();
    CounterC cp8(cp7++);cp8.display();
    CounterC cp9(cp7--);cp9.display();

    return 0;
}

2、重載負號(-)

下例中有3個Complex類 ComplexA、ComplexB 和ComplexC,3個類都重載了負號。

其中ComplexA使用類的非靜態成員函數方式重載,ComplexB使用類的友元函數方式重載,ComplexC使用普通函數方式重載。

#include <iostream>
using namespace std;

class ComplexA
{
public:
    //constructor
    ComplexA(double re, double im):real(re),image(im){}
    //Operator Overload : -
    ComplexA operator-(){return ComplexA(-real, -image);}
    //display
    void display(void){if (image>0)cout<<real<<"+"<<image<<endl;else cout<<real<<image<<endl;}

private:
    double real;
    double image;
};

class ComplexB
{
public:
    //constructor
    ComplexB(double re, double im):real(re),image(im){}
    //Operator Overload : -
    friend ComplexB operator-(ComplexB& ref){return ComplexB(-ref.real, -ref.image);}
    //display
    void display(void){if (image>0)cout<<real<<"+"<<image<<endl;else cout<<real<<image<<endl;}
private:
    double real;
    double image;
};

class ComplexC
{
public:
    //constructor
    ComplexC(double re, double im):real(re),image(im){}
    //GetData
    double GetReal(void){return real;}
    double GetImage(void){return image;}
    //display
    void display(void){if (image>0)cout<<real<<"+"<<image<<endl;else cout<<real<<image<<endl;}


private:
    double real;
    double image;
};

//Operator Overload : -
ComplexC operator-(ComplexC& ref){return ComplexC(-ref.GetReal(), -ref.GetImage());}

int main(void)
{
    ComplexA a1(1,2);a1.display();
    ComplexA a2(-a1);a2.display();

    ComplexB b1(1,2);b1.display();
    ComplexB b2(-b1);b2.display();

    ComplexC c1(1,2);c1.display();
    ComplexC c2(-c1);c2.display();

    return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM