專案
1.設計complex(復數類)
? 需求:1)實部,虛部re,im
? 2)重寫+=符號,呼叫friend_doapl函式,對兩個復數進行相加 其中+=函式呼叫一個全域函式_doapl(complex*,complext&)進行處理,這里只用完成兩個復數的相加
? 3)重寫+符號,這里只用完成兩個復數,復數和實數的相加
設計完成后的代碼
#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));
}
endif //MYCOMPLEX
設計:
1)確定成員變數以及get方法 思考函式const,real()和img需要加,因為不需要修改值,
2)確定多載符號operator +=方法,
complex& operator +=(const complex&);
? 思考回傳值是什么型別,我們在復數類計算時,經常 x+=y,等價于x = x+y. 因此,確定回傳的是原來的x的值,也就是this,我們可以得出,直接傳回參考,因為我們傳回去得并不是local variable,但為什么我們不設計是void型別呢?因為當我們計算x+=y的時候,我們可以直接通過參考改變x的值呀?
就比如:
complex& operator +=(const complex& c){
this.re = this.re+c.real();
}
原因就在于,在c++中可以連續復制,如 x1+=x2+=x3; 當發生這種情況的時候,參考必須回傳以供作為右值以供下一次的運算,
思考形式引數,能用參考得就用參考,且原值能不能修改呢? 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));
}
從complex得到的經驗
1)若方法不需要修改資料,一定加上const,因為const物件只能呼叫const方法,若方法不加const,const物件功能不全,
- 形式引數都應該傳遞參考,如果不需要修改,則一定加上const,否則原值可能被修改,若直接傳遞了值,則發生復制,會很慢,當然,char這種一個位元組的引數可以傳值,
3)回傳值也盡量用參考傳遞,快,但是一定不能回傳區域變數的參考,因為區域變數存在堆疊中,方法執行完之后記憶體就被回收了,
4)簡單的函式要加inline即使編譯器會自動選擇,
5).h檔案的劃分

其中,類宣告里的函式不用寫具體的形式引數,只用寫形式引數的型別即可,簡單的函式可以在類宣告部分就定義如 real()和Img(),復雜的應該在函式體外進行定義,最后,類內的函式均會自動加上inline,在類外定義的函式若比較簡單,應該手動建議編譯器使用inlien.
6)運算子多載時,若是雙目運算子 如 + 則應該定義為全域函式,
如z = x+y,使用+號時,不需要this的值,
與之相對的是單目運算子,如==或+=
如判斷 z==y 的時候,我們需要用到z的值,所以必須定義在類內,所以就沒有意義了
但簡單的如real()可以寫完函式體,復雜的函式應該在類定義區域完成函式體的撰寫,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/232898.html
標籤:其他
上一篇:填坑系列之OpenFeign
