C++類的構建--complex(複數)類的設計過程與思考總結

項目

1.設計complex(複數類)

​ 需求: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));
}

endif //MYCOMPLEX

設計:

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));
}
從complex獲得的經驗

1)若方法不須要修改數據,必定加上const,由於const對象只能調用const方法。若方法不加const,const對象功能不全。

  1. 形式參數都應該傳遞引用,若是不須要修改,則必定加上const,不然原值可能被修改。若直接傳遞了值,則發生複製,會很慢。固然,char這種一個字節的參數能夠傳值。

3)返回值也儘可能用引用傳遞,快。可是必定不能返回局部變量的引用,由於局部變量存在棧中,方法執行完以後內存就被回收了。

4)簡單的函數要加inline即便編譯器會自動選擇。

5).h文件的劃分

其中,類聲明裏的函數不用寫具體的形式參數,只用寫形式參數的類型便可。簡單的函數能夠在類聲明部分就定義如 real()和Img()。複雜的應該在函數體外進行定義。最後,類內的函數均會自動加上inline,在類外定義的函數若比較簡單,應該手動建議編譯器使用inlien.

6)操做符重載時,如果雙目運算符 如 + 則應該定義爲全局函數。

如z = x+y。使用+號時,不須要this的值。

與之相對的是單目運算符,如==或+=

如判斷 z==y 的時候,咱們須要用到z的值,因此必須定義在類內,因此就沒有意義了

但簡單的如real()能夠寫完函數體。複雜的函數應該在類定義區域完成函數體的編寫。

相關文章
相關標籤/搜索