C++ 面向對象高級開發 -- complex 類的實現


 

1. Object Based(基於對象) vs. Object Oriented(面向對象)

Object Based: 面對的是單一class的設計;

Object Oriented:面對的是多重classes的設計,class 和 class 之間的關系。

 

classes 的兩個經典分類:

  • class without pointer members -- complex
  • class with pointer members -- string

 

2. Header (頭文件)

  2.1 防衛式聲明

 

  2.2 把 complex 的實部和虛部寫成模板類

 

 

  2.3 inline

inline 關鍵字是對編譯器的建議。建議把某個函數定義為內聯函數。實際上,是否定義為內聯函數,由編譯器決定。

定義在類內的函數,都是 “提議” 為內聯函數。

 

  2.4 訪問級別

所有數據成員都應該是private;

供外部使用的函數成員都應該是public,只供類內使用的函數成員可以是private;

 

  2.5 構造函數

complex (double r = 0, double i = 0)
    : re (r), im (i)    // initialization list(初值列,初始值)
{}
complex (double r = 0, double i = 0) {
    re =  r;
    im = i;        
}

上述是 2 種形式的構造函數,其結果都是對 re 和 im 進行賦值。但是,使用 initialization list 的代碼效率更高,更彰顯編程素養

 

  2.6 不需要析構函數

complex 類沒有指針成員,因此不必使用析構函數。

 

  2.7 構造函數可以有很多個 -- overloading

下圖所示,由於構造函數 (1) 的形參全部具有默認值,所以重載函數 (2) 會造成調用混亂。

而 real() 函數,編譯器根據其返回值類型,形參類型和數量,定義了一個獨一無二的函數名稱(右下角所示)。

 

 

  2.8 構造函數為private權限

構造函數為private,即不允許外界創建對象。

舉例子,一個設計模式,singleton,只允許該類創建一個對象。通過類內的靜態函數創建對象。

 

  2.9 const member functions(常量成員函數)

若 real() 和 imag() 函數都沒有加 const 關鍵字,如下面2種使用方式,左邊是成立的,右邊卻不成立。原因在於,c1 是個 const 變量,若其調用 real(), real() 告訴編譯器可以修改 c1 的值,出現矛盾,報錯。

 

  2.10 返回值傳遞: return by value vs. return by reference( to const )

返回值優先考慮傳引用。

什么情況下可以返回引用?

若返回的變量A是在函數內創建,函數結束后,棧內存釋放,變量A銷毀。此時便不可以返回A的引用。

 

  2.11 參數傳遞: by value vs. by reference( to const )

 

  2.12 friend 友元

complex 類認可 _doapl() 是它的友元函數,則在該函數內部可直接訪問 complex 類的 private 數據成員。

 

相同 class 的各個 objects 互為友元,因此如下函數成立。

 

 

  2.13 操作符重載 -- 類內成員函數

在 complex 類內重載 += 運算符。其中,c1 作為重載運算符實參,對應的形參為 const 的引用類型。this 指針是類內成員函數的隱藏形參,此時 this 指針指向重載運算符的調用者,即 c2 . 

 

 

 

關於返回值的語法分析

重要概念:傳遞者無需知道接收者是以 reference 形式接收

如下,舉兩個例子:

  1. 函數 _doapl() ,返回值為 complex&,是接收者;函數內 return *this ,*this 作為傳遞者,  並非引用類型。
  2. 符號重載函數 += 的調用方式為  c2 += c1; 。實參 c1 為傳遞者,傳值;形參 const complex & r 作為接收者,是引用類型。

 

對於  c2 += c1;  ,符號重載函數的返回值可以為 void;

對於  c3 += c2 += c1; ,符號重載函數的返回值必須為 complex&。此時,c1 先加 c2,返回 complex & 類型的右值。之后調用該右值的符號重載函數,與 c3 相加。 

 

  2.14 符號重載函數 -- 全局函數

操作符 << 的重載,只能定義為全局函數。原因如下,

 cout << conj(c1); ,操作符 << 只能作用在左邊的 cout 上。cout 是輸出流對象,無法在其類定義中添加操作符 << 的重載函數。因此,只能將操作符 << 重載函數定義為全局函數。

 

操作符 << 重載函數的實現:

  • cout 是 ostream 類型的對象;
  • 形參優先使用傳引用;
  • 形參不能使用 const,因為往 os 中傳值,會改變 os 的狀態;
  •  cout << conj(c1); ,返回類型可以為 void;
  •  cout << c1 << conj(c1); ,返回類型必須為 ostream,且優先考慮返回引用。該語句的調用順序為, cout << c1,返回 ostream 類型的右值。調用該右值的 << 重載函數輸出 conj(c1).

 

 

注意事項總結

  1. 構造函數使用 initialization list;
  2. 函數是否定義為const;
  3. 函數參數盡量使用&,const;
  4. 函數返回值盡量使用&,const;
  5. 數據成員為private;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM