1. 程式人生 > >【C++】c++複數類Complex

【C++】c++複數類Complex

運算子過載應該注意以下幾個問題:

(1)c++語言中只能對已有的c++運算子進行過載,不允許使用者自己定義新的運算子。
(2)c++中絕大部分的運算子允許過載,不能過載的運算子只有以下幾個:
. 成員訪問運算子
.* 成員指標訪問運算子
:: 作用域運算子
sizeof 長度運算子
?: 條件運算子
(3)

過載不能改變運算子的操作物件(即運算元)的個數。例如,在c++語言中,運算子“+”是一個雙目運算子(即只能帶兩個運算元),過載後仍為雙目運算子。
(4)過載不能改變運算子原有的優先順序,也不能改變運算子原有的結合特性。例如,c++語言規定,乘法運算子“/”的優先順序高於減法運算子“-”的優先順序,故表示式:x = a/b-c; 的集合特性等價於 x = (a/b)-c;。
(5)運算子過載函式的引數至少應有一個是類物件(或類物件的引用),即運算子過載函式不能全是c++預定義的基本資料型別。例如:
int operator+ (int x,int y)
{ return x+y; }
int operator+ (int x,int y)
{ return x-y; }
以上兩個函式構成了過載,如果有表示式:5+3,它的結果是8呢?還是2呢?顯然,這是絕對不允許的!
(6)雙目運算子一般可以被過載為友元運算子過載函式或者成員運算子過載函式,但有一種情況,必須使用友元函式!

例如:如果將一個類AB的物件與一個整數相加,可以用成員運算子函式過載“+”運算子。
AB::operator+ (int x)
{
AB tmp;
tmp.a = a+x;
tmp.b = b+x;
return tmp;
}
若ob1和ob2是類AB的物件,則以下語句是正確的:
ob2 = ob1+200;這條語句被c++編譯系統解釋為:ob2 = ob1.operator+ (200);
由於物件ob2是運算子“+”的左運算元,所以它可以呼叫“+”運算子過載函式operator+(),執行結果是ob1資料成員a和b都加上一個整數200。然而,以下語句就不能工作了:

ob2 = 200 + ob1;這條語句被c++編譯系統解釋為:ob2 = 200.operator+(ob1);
由於運算子“+”的左運算元是一個整數200,而不是該類物件,不能呼叫該類的成員運算子過載函式,所以編譯時會出錯。如果定義以下兩個友元運算子過載函式:
friend AB operator+ (AB ob,itn x); //運算子”+”的左側是類物件,右側是整數
friend AB operator+ (itn x,AB ob); //運算子”+”的左側是整數,右側是類物件
當類AB的一個物件與一個整數相加時,無論整數出現在左側還是右側,使用友元運算子過載函式都能得到很好的解決。

下面是將運算子過載成成員運算子過載函式:

class Complex
{
public:
    /*************複數類Complex預設成員函式*********************/
    Complex(double real = 0.0, double image = 0.0)       //建構函式
    {
        _real = real;
        _image = image;
    }
    Complex(const Complex& c)                            //拷貝建構函式
    {
        _real = c._real;
        _image = c._image;
    }  
    Complex& operator= (const Complex& c)                //賦值操作符過載
    {
        if (this != &c)//防止自賦值
        {
            _real = c._real;
            _image = c._image;
        }
        return *this;
    }
    ~Complex()                                          //解構函式
    {}
    /*************複數類Complex基本操作函式*********************/
    void Display()                                      //列印複數
    {
        cout << "_real  : " << _real << "  ";
        cout << "_image : " << _image << endl;
    }
    Complex operator+ (const Complex& c)               //+運算子過載
    {//不能返回臨時變數的引用
        Complex tmp;
        tmp._real = _real + c._real;
        tmp._image = _image + c._image;
        return tmp;
    }
    Complex operator- (const Complex& c)               //-運算子過載
    {
        Complex tmp;
        tmp._real = _real - c._real;  //測試當相減為負數時
        tmp._image = _image - c._image;
        return tmp;
    }
    Complex& operator+= (const Complex& c)            //+=運算子過載
    {
        _real += c._real;//把+=後的結果賦給_real,即this的值發生改變
        _image += c._image;
        return *this;
    }
    Complex& operator-= (const Complex& c)            //-=運算子過載
    {
        _real -= c._real;//把-=後的結果賦給_real,即this的值發生改變
        _image -= c._image;
        return *this;
    }
    Complex operator++ (int)                           //後置++
    {//這裡的int型別引數只是用來區別字尾“++”與字首“++”,此外沒有任何作用
        Complex tmp(*this);
        _real++;//(*this)._real++;只需對實部加1
        return tmp;
    }
    Complex& operator++()                              //前置++
    {
        _real++;
        return *this;
    }
    Complex operator-- (int)                           //後置--
    {
        Complex tmp = *this;//呼叫拷貝建構函式
        _real--;
        return tmp;
    }
    Complex& operator-- ()                             //前置--
    {
        _real--;
        return *this;
    }
    Complex operator*(const Complex& c)//(ac-bd)+(bc+ad)i
    {
        Complex tmp;
        tmp._real = (_real*c._real) - (_image*c._image);
        tmp._image = (_image*c._real) + (_real*c._image);
        return tmp;
    }
    Complex operator/(const Complex& c)//(bc-ad)/(c^2+d^2)i
    {
        Complex tmp;
        tmp._real =(_image*c._real) - (_real*c._image);
        tmp._image = pow(c._real, 2) + pow( c._image, 2);
        return tmp;
    }
private:
    double _real;     //實部
    double _image;    //虛部
};

總結:

是否將運算子過載成友元運算子過載函式,決定權在於你。謹慎一點的話,建議過載成友元運算子過載函式。