
| 實習目標 | 練習定義型態轉換建構元與型態轉換運算子 |
|---|---|
| 步驟一 | 這次實習接續實習 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 |