U步驟:我們需要一個策略。由於我們的目的是減少programmer犯錯的機會,因此採取策略:檢視program code,找出容易導致programmer犯錯的code。
先看一個程式片段:
上面main函數讀起來,可以說是以u這個變數表示向量;和向量u的定義、使用相關的敘述有
- line 51: int dim_u; (向量的維度)
- line 52: double * u; (double 指標,指到向量記憶體中的位置)
- line 55: u = new double[dim_u];(配置記憶體,佔用連續的dim_u個double,u為這塊記憶體的beginning address)
- line 71: delete [] u; (釋放u佔用的記憶體)
- line 36 (and other lines): p += u[i]*v[i];(取用第i個分量)
好消息:C++可以幫上忙!C++的class可以讓我們把這些構成向量的變數、變數間的關係、變數與運算子間的關係做一個統合。
壞消息:你得學會如何將散落各處的資料、函數打包。(好吧,這算不上是一個壞消息 :)
列出新的子問題如下:
SP3: 統合向量相關變數、運算、函數,以物件表達,修改相關函數,使其接受並使用向量物件。
當此問題解決後,programmer使用物件時不需自行關聯獨立的變數。
現在未解的問題有SP3 及 SP2,讓我們先解 SP3。
T7 宣告新的向量型態,決定它打包的資料與函數。
T8 修改相關函數以使用新的向量型態
更新待辦工作如下:
C步驟:先做T7。將新的類別型態(class type)稱為vector,經過U步驟地分析得知,
- vector類別型態打包兩項資料double []與int (學習課題:class, data member, member functions, private, public)。
- 定義vector類別型態變數的建構元(constructor) (學習課題:constructor, initialization list, dynamic memory allocation, zeroing)
- 回收被vector類別型態變數佔用的記憶體用的解構元(destructor) (學習課題:scope and lifetime of a variable, destructor, memory deallocation)
- 向量分量取用函數(accessor function)(學習課題:operator overloading, return by reference)
- 向量維度的讀取函數(getter function) (學習課題:const member function)
class vector {
private:
double * _v;
int _dim;
public:
vector(int dim):_dim(dim){
_v = new double[_dim];
for (int i=0; i<_dim; ++i)
_v[i]=0;
}
~vector() {
delete [] _v;
}
double & operator [](int i) const {
return _v[i];
}
int dim() const {
return _dim;
}
};
有了 vector class 型態,接著處理T8。
T8的學習課題:model of a variable in memory, runtime memory model of a program, call by reference vs call by value, copy constructor, deep copy vs shallow copy。
原 main函數片段
可修改如下:
新程式line 70
vector u(dim_u);
呼叫建構元,定義vector型態的物件u,它的維度為dim_u;line 70 取代原程式line 51, line 52及line 55。
新程式line 71
inputVector(u);
取代舊程式line 56,
inputVector(u, dim_u);
呼叫inputVector時只需傳入vector型態的物件u,而不傳入它的維度dim_u。
完成的程式請點連結下載。
L步驟:請檢查round 3的程式碼是否優於前一版,讓programmer犯錯的機會減少。
除此之外,讓我們再次以programmer的觀點進行回顧。這次,回想自round 1起,我們為求方便,每當完成一個工作時,(例如round 1中的innerProduct函數,)經常借用main函數來測試這個工作完成的code。(例如,準備好兩個向量,將作為參數他們傳給innerProduct函數做計算,然後將結果輸出到console:見round 3程式。)
/*
double a[2]={0,1};
double b[2]={1,0};
double c[3]={1,2,3};
vector u(2,a);
vector v(2,b);
vector w(3,c);
double prod;
if (innerProduct(prod,u,v))
cout << "inner product is " << prod << endl;
else
cout << "Dimension error!" << endl;
if (innerProduct(prod,u,w))
cout << "inner product is " << prod << endl;
else
cout << "Dimension error!" << endl;
*/
我們找到一個議題:讓test code脫離 main函數存在。
© Y C Cheng, 2013. All rights reserved.
沒有留言:
張貼留言