實習目標 | 練習定義型態轉換建構元與型態轉換運算子 |
---|---|
步驟一 | 這次實習接續實習 3: 複數類別, 請下載實習 3 所完成的 Complex 類別程式碼 |
步驟二 | 在類別裡原先我們設計了 Complex::setValue(double, double) 的成員函式來初始化每一個
Complex 物件, 請你將這個函式移除, 另外撰寫一個建構元函式
Complex::Complex(double, double);來取代 setValue() 函式的功能, 並且在程式其它地方完成必要的修改, 請檢查原先的測試程式是不是都正確地運作, 這個時候我們應該慶幸上一次在寫的時候寫了很多 assert 敘述, 這些敘述自動幫我們檢查修改過的程式是不是對的, 如果那時設計得好, 現在要用眼睛慢慢檢查的機會就小很多了。 不是說慢慢地檢查很不好, 而是你要檢查的話一定要把上一次的程式完整了解過才能檢查, 上一次設計時也許有一些設計的取捨也許你現在已經忘了, 這都是很容易在軟體裡產生 bug 的時機, 所以以前很多很有經驗的程式師, 都是死也不肯修改舊的程式的, 就算程式看起來很簡單, 他的經驗告訴他, 增加一點點的功能可能會增加很多的 bugs, 在沒有預防的情況下這的確是事實, 所以以往客戶永遠沒有辦法理解為什麼程式設計者那麼頑固, 明明是很小的功能也不肯直接去改... |
步驟三 | 假設你宣告一個函式需要接受 Complex 類別的物件作為參數, 例如
void Complex::addTwice(Complex data) { m_real += data.m_real * 2; m_imaginary += data.m_imaginary * 2; }正常的呼叫方法如下 Complex a(1,2), b(3,4); a.addTwice(b);有沒有辦法讓下面的呼叫也正常運作呢? double c=10.0; a.addTwice(c);在上面這個敘述中基本上希望將傳進去的實數 c 當成是實數部份把它加在複數 a 上, 一種方法是作出一個暫時性的 Complex 物件, 再傳入函式裡運算, 請自己先想一下怎麼寫, 再測試下面的程式: a.addTwice(CComplex(c, 0));第二種方法就是我們要大家寫的型態轉換建構元了, 我們知道在下面的程式裡 Compiler 會自動幫我們轉換資料: double square(double x) { return x*x; } ... int z=10; double y; y = square(z);int 型態的變數 z 裡面的資料會自動地轉換為 double 型態, 然後拷貝到變數 x 當中進行運算, 我們現在就是希望能夠有這種功能, 方法很簡單, 請定義一個建構元如下: Complex::Complex(double x) :m_real(x), m_imaginary(0.0) { }然後再測試 a.addTwice(c); 的程式碼, 或是 a = 10.5; 應該都可以用了吧, 有了這個建構元, Compiler 就可以自動幫你由 double 型態建構出一個 Complex 類別的物件出來, 並且傳進函式中處理。 它看起來和一般的建構元沒有什麼差異, 不過也有人特別叫它型態轉換建構元 (type conversion operator)。 其實還有另外一種方法可以運用上一步驟的建構元 Complex::Complex(double,double) 來完成我們在這一步驟裡所作的轉換, 就是用函式預設的參數, 自己想一想囉! (請參考投影片 page8, 請注意預設的參數必須在類別的定義裡面設定, 不是在類別的實作裡設定) |
步驟四 |
接下來我們來寫型態轉換運算子 (type conversion operator)
我們在 C 中會看到下列的強制型態轉換的程式片段: int x; double y=20.5; x = (int) y;(int) 就是型態轉換的運算子, 在 C++ 中我們可以替某一個類別的物件定義一個型態轉換的運算子, 例如我們可以替 Complex 類別定義 (double) 的運算子, 將 Complex 類別的物件轉換為 double 型態的資料, 當然我們需要先界定這個轉換的意義到底是什麼, 假設我們把一個複數物件轉換成它的長度如下: Complex a(10.5, 20.3); double magnitude; magnitude = a;如果沒有特別的定義, C++ compiler 會說上面這個敘述是錯的, 請定義下面的成員函式: Complex::operator double() { return sqrt(m_real*m_real+m_imaginary*m_imaginary); }如此前面的轉換就可以順利進行了, 同時你也可以用下面兩種敘述: magnitude = (double) a; magnitude = double(a);效果都是一樣的。 另外如果你有一個函式接受一個 double 型態的參數, 你現在也可以把一個 Complex 的物件傳進去, compiler 會自動幫你轉換。 |
步驟五 | 請助教檢查後, 將所完成的 專案 (只需保留 .cpp, .h, .sln 以及 .vcxproj 檔案即可; 刪除掉 .suo, .sdf, .filters, .users, debug\ 資料匣, 以及 ipch\ 資料匣下的所有內容)壓縮起來, 選擇 Lab7-1 上傳, 後面的實習課程可能需要使用這裡所完成的程式 |
回
C++ 物件導向程式設計課程
首頁
製作日期: 03/23/2013 by 丁培毅 (Pei-yih Ting) E-mail: pyting@mail.ntou.edu.tw TEL: 02 24622192x6615 海洋大學 電機資訊學院 資訊工程學系 Lagoon |