C 複數運算的運算子過載

2021-07-03 22:09:43 字數 4961 閱讀 4501

假設我們有如下複數類:

class complex

//預設建構函式

complex(double r,double i)//建構函式

}

complex sum,c1,c2;

sum=c1+c2;

要在以前,我們是這麼計算的:

complex sum,c1,c2;

sum.real=c1.real+c2.real;

sum.image=c1.image+c2.image;

看起來似乎也不是很複雜,但如果這個類的屬性很多,有好幾個甚至好幾十個呢?這時候c++運算子過載的優勢就體現出來了。實現了運算子過載後上述的sum=c1+c2就能直接進行計算了。

實現運算子過載之前我們先要知道其表現形式有兩種:過載為成員函式,過載為友元函式。

不懂?不要急!我們先從乙個簡單的函式出發:

complex operate + (complex c2)

函式型別 operate 運算子 (形參列表)

可以發現這個過載函式將加的運算封裝進了complex類的+運算中使其能支援該類的直接運算。

+ 運算實現兩個數相加自然需要兩個引數,為何只有c2乙個引數呢?

因為上述這段**將 complex類的 + 過載為了成員函式,其實它的形參表裡隱含了乙個this指標,實質上這個成員函式有兩個形參(complex* this,complex c2),只不過被隱含了。

即該函式能利用this指標直接訪問該類的private變數real和image,this指標也可省略不寫。

這一規則也就意味著過載為類的成員函式時必須寫成靜態形式,即在函式型別前面加上 const 關鍵字,以防止this指標的濫用改變了不該改變的成員變數。

另外,為了有效利用c++的高效,傳參時應使用引用而不是值,但不在本文討論範圍故不在贅述。

優化後的**:

const complex operate + (const complex &c2)	//第乙個const表示函式唯讀,防止this指標濫用 

那麼這個運算能被過載為友元函式麼?什麼是友元函式?

先來看這段**:

friend complex operator +(const complex &c1,const complex &c2)

這是 complex 類的 + 過載為了友元函式。由於不是成員函式,因此沒有隱含的 this 指標,故要把 + 左右兩邊的引數都傳進去,為了使該函式能夠訪問其他 complex 物件的成員變數 real 和 image,

必須申明為友元函式。 

宣告為友元函式更重要的乙個理由:過載乙個運算子,使之不再需要用"物件.成員名"的形式呼叫。參見下表。

該友元函式的形參代表了依自左向右次序排列的各運算元。

為了區分前置後置運算,後置單目運算子++、--的過載,形參表中要增加乙個 int,但不必寫形參名。

運算子成員函式的設計:

運算子使用形式

等價式雙目運算子@

x1 @ x2

x1.operate @ (x2)

前置單目@

@ xx1.operate @()

後置單目@

x @x1.operate @(0)

運算子友元函式的設計:

運算子使用形式

等價式雙目運算子@

x1 @ x2

operate @ (x1,x2)

前置單目@

@ xoperate @(x1)

後置單目@

x @operate @(x1,0)

* 後置單目運算中多出來的0引數僅表示其後置意義。

由上可知,過載為成員函式時:形參個數 = 原運算元個數 -1 (-1為隱含的this指標)(後置++ --除外)  

過載為友元函式時:形參個數 = 原運算元個數

為類設計過載操作符的時候,必須選擇是將操作符設定為 類成員還是友元函式。在某些情況下,程式設計師沒有選擇, 操作符必須是成員;在另一些情況下,有些經驗原則可指導我們做出決定。

遵循下列原則:

賦值(=)、下標()、呼叫(())和成員訪問箭頭(->)等操作符必須定義為成員,將這些操作符定義為非成員函式將在編譯時標記為錯誤。  

像賦值一樣,復合賦值操作符通常應定義為類的成員函式,與賦值不同的是,不一定非得這樣做,如果定義非成員

復合賦值操作符,不會出現編譯錯誤。

改變物件狀態或與給定型別緊密聯絡的其他一些操作符, 如自增、自減和解引用,通常就定義為類成員。 

對稱的操作符,如算術操作符、相等操作符、關係操作 符最好定義為友元函式。 

>>、《操作符定義為友元函式。

運算子 + 與 += 的過載區別與聯絡?

回過頭來看,在過載了 + 運算子時,通常會同時過載 += 運算子,思考下這兩個運算子應該怎麼過載? 

operator+  通常定義成非成員,operator+=通常定義成成員 

operator+= 返回運算元的引用,而operator+返回乙個臨時物件

通常我們用 operator += 來實現 operator+

其它算術操作符(+,-,*,/,%)同+ 

廢話少說,上**解釋:

//過載 +=(複數相加)

complex operator +=(const complex &c2)

//過載 +(複數相加)

friend complex operator +(const complex &c1,const complex &c2)

基於效率考慮,這樣可以使 += 返回乙個運算元的引用,而 + 不行。(故 += 效率遠大於 + )

最後幾點:

如果乙個運算子想用某個基本型別的資料呼叫,它就必須定義成全域性的友元函式。

如: complex a; complex b = 2 + a;   

這個 operator+ 不能是 complex 類的成員函式,也不能是其他類的成員函式,

因為不存在乙個函式: 

complex & int.operator+ ( complex& rhs) 

//複數相關運算的運算子過載

#include using namespace std;

class complex

complex(double r,double i)

void showcomplex()

//過載 =

complex operator =(const complex &c)

//過載 -=

complex operator -=(const complex &c2)

//過載 +=(兩個複數相加)

complex operator +=(const complex &c2)

//過載 +=(複數與實數相加)

complex operator +=(double c2)

//過載 *=

complex operator *=(const complex &c2)

//過載/=

complex operator /=(const complex &c2)

//過載 +(複數相加)

friend complex operator +(const complex &c1,const complex &c2)

//過載 +(複數與實數相加)

friend complex operator +(const complex &c1,double c2)

//過載 -

friend complex operator -(const complex &c1,const complex &c2)

//過載 *

friend complex operator *(const complex &c1,const complex &c2)

//過載 /

friend complex operator /(const complex &c1,const complex &c2)

};int main()

{ complex c;

complex c1(1.5,2.5);

complex c2(2.5,3.5);

cout<<"c1:\t";

c1.showcomplex();

cout<<"c2:\t";

c2.showcomplex();

c=c1+c2;

cout<<"c1+c2:\t";

c.showcomplex();

cout<<"c1+5:\t";

c1+=5;

c1.showcomplex();

c=c1-c2;

cout<<"c1-c2:\t";

c.showcomplex();

c=c1*c2;

cout<<"c1*c2:\t";

c.showcomplex();

c=c1/c2;

cout<<"c1/c2:\t";

c.showcomplex();

cin>>c1;

cout<<"c:"<

可以過載c++中除下列運算子之外的所有運算子:

..*:: ?:sizeof typeid# static_cast<>dynamic_cast<>

const_cast<>  reinterpret_cast<>    ||   &&   ,

可過載運算子: 

+-* /%^&| ~!=

<>

<=>=++-->> ==!=+=-=/= %=^=&=|=*=

<<=>>= ()->->*newnew deletedelete

過載加法運算子的複數運算

題目內容 定義乙個複數類,並過載加法運算子 和賦值運算子 以適用對複數運算的要求。輸入格式 依次輸入兩個複數的實部和虛部 輸出格式 先按照要求格式輸出兩個複數,然後輸出這兩個複數的和 輸入樣例 1 23 4 輸出樣例 1 j2 3 j4 4 j6 時間限制 500ms記憶體限制 32000kb in...

C 複數類運算子過載

實現運算子過載有兩種形式 過載為成員函式 過載為友元函式。includeusing namespace std class complex complex double r,double i complex const complex rhs complex operator const compl...

C 運算子過載,複數類

複數類 ccomplex c 的運算子過載 使物件的運算表現的和編譯器內建型別一樣。include using namespace std class ccomplex ccomplex operator const ccomplex src void show 運算子的過載 operator 前置...