【高質量C++/C總結9】複數類complex解析

說在開始:

我提煉了《C++ Primer》、《侯捷C++》、《高質量程序設計指南——C/C++語言》等資料中的重要部分,並總結成此博文。其中涉及到許多我個人對C++的理解,如若有不合理之處,還請朋友們多多指出,我會虛心接受每一個建議。

作者:憨豆酒(YinDou),聯繫我[email protected],熟悉圖形學,圖像處理領域,本章的源代碼可在此倉庫中找到: https://github.com/douysu/person-summary 如果大家發現錯誤以及不合理之處,還希望多多指出。

complex代碼

complex.h

#ifndef COMPLEX_H
#define COMPLEX_H
#include <iostream>
using namespace std;
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();
}
ostream&
operator << (ostream& os, const complex& x)
{
	return os << '(' << real(x) << ',' << imag(x) << ')';
}
#endif

main.cpp

#include "complex.h"
int main() {
	complex c1(2, 1);
	complex c2(5);
	printf("%d", sizeof(c1));
	c2 += c1;
	cout << c2;
	cin.get();
}

涉及到的細節問題

定義部分

1. 在頭文件中防禦式常數定義
2. class的head,在body裏面開始做動作
3. 數據應當放在private裏面,實部和虛部
4. 對外發表的函數應當放在public當中,構造函數要不要默認值,參數值考慮是pass by value還是pass by reference
5. 構造函數的初始列,將實部虛部設置爲初始值
6. 考量構造函數還需要做什麼事情。也就是{}括號中的內容
7. 設計複數類應該支持什麼樣的能力,這裏設計了+=的能力。函數有兩種選擇:成員函數和非成員函數。
8. 設計一個取得其private成員的public函數。函數的類型需要考慮要不要加const,如果函數當中不會改變data的時候應該使用const,這裏只是取出實部和虛部,所以這裏加上了const
9. 定義一個friend函數,因爲要直接取得複數類的私有成員。

函數的實現

10. 因爲屬於class裏面的,所以操作符的重載需要寫成complex:: operator +=類型的。
11. 然後思考這個函數的參數是什麼,成員函數中的參數都會有一個隱藏的this指針,這個this指針會優先傳遞成員函數中。對於不在修改的參數應該加上const。
12. 考慮成員函數的返回內容,最好傳遞reference,如果傳遞出去的東西不是local object,儘量去傳遞reference
13. 考慮函數是不是可以變成inline函數,能不能成爲內聯函數不知道,只有編譯器纔可以做出最終的決定。
14. 加的動作不是本身成員函數中去做的,而是交給另一個函數去做的。
15. 另外附屬一些動作都可以設計爲非成員函數,也就是全局函數。爲什麼不把+這個動作設計成成員函數呢 ?需要注意的是,複數不僅可以+複數,也可以加float,int,如果只把+這個動作放到class中,只能完成複數與複數的相加
16. 左邊的參數+右邊的參數   會生成一個local的對象,這時候函數不能在傳遞引用。當函數執行完畢後,對應的對象也會銷燬,這裏應當提起重視。應該return by value。
17. 這裏有一個新的語法。class的名稱加上小括號。例如:complex();此就是創建了一個臨時的object。
特殊的操作符重載 <<
18. 因爲要輸出複數的形式,簡單的<<操作符無法達到要求了,在C++標準庫當中對此操作符<<進行重載。
19. 操作符重載有兩種方式:成員函數和非成員函數 。
20. 使用者可能使用連串的輸出cout<<c1<<endl,如果return by value 就會出現錯誤,此時應該使用return by reference
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章