需求:1)實部,虛部re,imc++
2)重寫+=符號,調用friend_doapl函數,對兩個複數進行相加 其中+=函數調用一個全局函數_doapl(complex*,complext&)進行處理。這裏只用完成兩個複數的相加函數
3)重寫+符號,這裏只用完成兩個複數,複數和實數的相加this
設計完成後的代碼設計
#ifndef __MYCOMPLEX__ #define __MYCOMPLEX__ class complex; complex& __doapl(complex* ths, const complex& r); complex& __doami(complex* ths, const complex& r); complex& __doaml(complex* ths, const complex& r); class complex { public: complex(double r = 0, double i = 0) : re(r), im(i) { } complex& operator += (const complex&); double real() const { return re; } double imag() const { return im; } private: double re, im; friend complex& __doapl(complex*, const complex&); }; inline complex& __doapl(complex* ths, const complex& r) { ths->re += r.re; ths->im += r.im; return *ths; } inline complex& complex::operator += (const complex& r) { return __doapl(this, r); } inline double imag(const complex& x) { return x.imag(); } inline double real(const complex& x) { return x.real(); } inline complex operator + (const complex& x, const complex& y) { return complex(real(x) + real(y), imag(x) + imag(y)); } inline complex operator + (const complex& x, double y) { return complex(real(x) + y, imag(x)); } inline complex operator + (double x, const complex& y) { return complex(x + real(y), imag(y)); }
1)肯定成員變量以及get方法 思考函數const,real()和img須要加,由於不須要修改值。code
2)肯定重載符號operator +=方法。對象
complex& operator +=(const complex&);
思考返回值是什麼類型。咱們在複數類計算時,常常 x+=y,等價於x = x+y. 所以,肯定返回的是原來的x的值,也就是this。咱們能夠得出,直接傳回引用,由於咱們傳回去得並非local variable。但爲何咱們不設計是void類型呢?由於當咱們計算x+=y的時候,咱們能夠直接經過引用改變x的值呀?blog
就好比:內存
complex& operator +=(const complex& c){ this.re = this.re+c.real(); }
緣由就在於,在c++中能夠連續複製,如 x1+=x2+=x3; 當發生這種狀況的時候,引用必須返回以供做爲右值以供下一次的運算。get
思考形式參數。能用引用得就用引用。且原值能不能修改呢? x = x+y this指的是x的數據,形式參數指的是y的數據。x的數據發生了改變,可是y的沒有。因此咱們得出,形式參數要加上const。編譯器
3)全局函數_doapl(complex&,complext&)
多是由於其餘地方也要用到,因此就把它寫成了全局函數而不是成員函數。爲了實現 operator+=調用它,咱們得將它聲明爲一個友元。
其成員變量兩個一個是complex*而非complex&的緣由是,要傳入this,與operator+=發生聯動。
4)設計 operator+重載
思考返回值類型,假設有 x3 = x1+x2。x3必然是在函數內新建一個變量並返回,因此不能返回一個局部變量的引用。只能使用值傳遞。
此外,咱們能夠注意到,operator+定義在了類外,由於它不須要this這個變量,且operator+二目運算符只容許有兩個參數,要想不加入this(類內函數默認添加this形式參數),只能寫在類外做爲成員函數。
那還有幾個問題,複數相加有不少種可能,如下是應該考慮的可能性,咱們必須根據這些可能性設計函數的重載:
/** 有三種狀況 1.複數加複數 2.複數+double 3.double+複數 **/ inline complex operator + (const complex& x, const complex& y) { return complex (real (x) + real (y), imag (x) + imag (y)); } inline complex operator + (const complex& x, double y) { return complex (real (x) + y, imag (x)); } inline complex operator + (double x, const complex& y) { return complex (x + real (y), imag (y)); }
1)若方法不須要修改數據,必定加上const,由於const對象只能調用const方法。若方法不加const,const對象功能不全。
3)返回值也儘可能用引用傳遞,快。可是必定不能返回局部變量的引用,由於局部變量存在棧中,方法執行完以後內存就被回收了。
4)簡單的函數要加inline即便編譯器會自動選擇。
5).h文件的劃分
其中,類聲明裏的函數不用寫具體的形式參數,只用寫形式參數的類型便可。簡單的函數能夠在類聲明部分就定義如 real()和Img()。複雜的應該在函數體外進行定義。最後,類內的函數均會自動加上inline,在類外定義的函數若比較簡單,應該手動建議編譯器使用inlien.
6)操做符重載時,如果雙目運算符 如 + 則應該定義爲全局函數。
如z = x+y。使用+號時,不須要this的值。
與之相對的是單目運算符,如==或+=
如判斷 z==y 的時候,咱們須要用到z的值,因此必須定義在類內,因此就沒有意義了
但簡單的如real()能夠寫完函數體。複雜的函數應該在類定義區域完成函數體的編寫。