如果您對C++的基本語法不熟悉,建議可以先閱讀 C++ Primer 4/e 試讀本第一章(侯捷譯) http://epaper.gotop.com.tw/pdf/ACL021200.pdf
2015年6月29日 星期一
Class template 類別樣版/模板
使用具有動態配置及記憶空間管理能力的 class 來存取資料,可以分擔主程式開發的工作,如上一篇 改善記憶體管理效能 裡的 class myData。但 myData 只處理 int 型態的資料,若要處理其他資料型態,例如來源資料是帶有小數點的浮點數,那又得另外撰寫一個 class myfloatData 來處理,不太理想。
針對這樣的問題,C++ 提供 Class template 的設計方法來解決,基本上就是把 class 宣告成類別樣板,以提高程式碼的可重覆使用性。Class template 基本語法:
template <class 變數型態名稱>
class 類別名稱{
// ........
變數型態名稱 ........
};
以 Class template 方式改寫上一篇 class myData 如下
#include <iostream>
template <class dType>
class myData
{
//私有區段,只有class內部程式可存取
private:
int _boundary; //陣列空間上限
//公用區段,class內外部程式均可存取
public:
int len;
dType *data; //用來存放所有輸入資料的記憶空間指標
//Member function
myData() //建構函式,當物件產生時會自動執行
{
len=0; //資料長度歸0
_boundary=10; //邊界設為10
data=new dType[_boundary]; //配置10個dType記憶空間
}
~myData() //解構函式,當物件消滅時會自動執行
{
delete [] data; //釋放data記憶空間
}
void add(dType d)
{
if (len>=_boundary-1) //資料滿了,增加記憶空間
{
dType *nptr=new dType[_boundary+10]; //多配置10個dType記憶空間
for(int i=0; i<len; i++)
nptr[i]=data[i]; //把舊資料複製到新的位置
delete [] data; //釋放舊的記憶空間
data=nptr; //資料指標指向新的位置
_boundary+=10;
}
data[len++]=d; //把參數d放在最後的位置後再把資料長度+1
}
};
int common_divisor(int a, int b) //遞迴函式1
{
return (a%b==0) ? b : common_divisor(b,a%b); //交換位置轉轉相除
}
int common_divisor(int d[], int n) //遞迴函式2
{
if(n==1)
return d[0];
if(n==2)
return common_divisor(d[0],d[1]); //呼叫遞迴函式1
if(n>2)
return common_divisor(common_divisor(d,n/2),
common_divisor(&d[n/2],n-n/2) ); //呼叫遞迴函式2
return 0; //n小於1才會發生
}
int main()
{
int d;
myData<int> object1;
std::cout << "請輸入n個正整數,輸入完成請按 Ctrl-Z" << std::endl;
while ( std::cin >> d )
object1.add(d);
std::cout << "最大公因數=" << common_divisor(object1.data,object1.len);
return 0;
}
跟原來的程式幾乎一樣,差別只是原來在 class 中寫死的 int,改為未知型態代名 dType。主程式中則以 myData<int> object1; 宣告來指定 dType 的實際型態 int。將來若需處理浮點數資料,只要在程式裡宣告 myData<float> object2; 就可以使用了。
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言