在C++中Template是什麼呢?為什麼要有這個東西?
簡單來說,如果今天我要做兩個數字的總合函式,傳統方式該怎麼寫呢?
int SumInt(int iA, int iB)
{
return (iA + iB);
}
float SumFloat(float fA, float fB)
{
return (fA + fB);
}
由此可見,傳統的方式必須要考慮傳入和傳回的變數型態,然後撰寫各自的函式,可是其實內容卻是相同的演算法,就只有型態的不同而已。所以幾乎是相同的程式碼要複製很多份,在修改其中的變數型態。
聰明的工程師怎麼可以做出如此愚蠢的事,當然要至做出一種樣本,讓使用的人來決定該怎麼用才對。這種迂腐的行為實在是太不應該了,所以就有Template的存在。
有圖有真相,請看
Template的宣告方式為:
template<class T>
ReturnType FunctionName(parameter list)
所以上面兩個函式可以用template改寫成:
template<class T>
T Sum(T tA, T tB)
{
return (tA + tB);
}
寫好這個函式之後,當要執行相同型別的加法運算時,就可以呼叫這個樣板函式,呼叫的方式為:
int iA = 10, iB = 20;
int iTotal = Sum<int>(iA, iB);
當然你也可以定義複雜一點的樣板函式,以Sum這個函式來看,加總兩個不同型別並回傳不同型別是可以做到的,請往下看。
template<class Return, class Type1, class Type2>
Return Sum(Type1 tA, Type2 tB)
{
return ((Return)tA + (Return)tB);
}
使用範例:
int iA = 10;
float fB = 20.5f;
double dTotal = Sum<double, int, float>(iA, fB);
這些都還只是牛刀小試,Template的功用還不只如此,還可以應用到class上。今天如果是個Class,它做的事情可能有加法、乘法、平均或其他更多的運算,我要針對不同的型態去寫幾乎一樣的class,又假如今天這些功能是隨著時間,一項一項被要求多加的功能,而且只有Int class要加,float class不要加,我們要怎麼再"複製"並"修改"這N份不同型態的Code?
光想就是一件累死人的事情了。
這樣也很少會所有型態的class都在同一份檔案中,就像他們在混沌之海中各自漂浮一樣。
咦?那如果說傳回值的型態也不一定的話...。
沒錯。
如果template這麼方便,那不如把它用在宣告變數如何?
使用template的值是在Compile時就要處理完的(跟Define一樣),所以我們沒辦法直接用template宣告一個變數。
但是我們可以間接的使用template來宣告變數,如以下的例子。
template<class
Datatype, int SIZE>
class ksArray
{
public:
void Set(Datatype item, int index)
{
m_array[index] = item;
}
// get function, gets an index
Datatype Get(int index)
{
return m_array[index];
}
private:
//
the array.
Datatype m_array[SIZE];
};
上面的template中有一段”int SIZE”,所以我們也可以在template中寫一些像是Define的資訊。
template< class Datatype, int SIZE, Datatype DEFAULT >
1: Array< int, 5, 0 > array1;
代表宣告了一個長度5的int陣列,陣列元素的初始值0
2: Array< int, 10, 42 > array2;
代表宣告了一個長度10的int陣列,陣列元素的初始值42
3: Array< float, 5, 0.5f > array3;
代表宣告了一個長度5的float陣列,陣列元素的初始值0.5
使用時還可以順便做陣列的邊界檢查呢(當然要自行在class中寫這些判斷)。
上圖就是Template的目的,其實就是”方便”,他跟Define是很類似的東西,上頭一直強調的,原本需要複製並修改的Code,現在使用template就可以省略這些步驟了,因為等於它幫我們做了。幫助我們省略這些繁瑣的步驟,除了方便外,這同時也代表了Code的可讀性變好了,變簡潔了,也讓除錯變得比較容易。
留言列表