43
1 第第第第 第第Template

第十五章

Embed Size (px)

DESCRIPTION

第十五章. 樣板( Template ). 第十五章 樣板( Template ). 樣板是 C++ 為了方便能夠快速生產程式而提供的新功能,在最初期的 C++ 版本中,並不提供樣板機制。所謂樣板( Template ),就是讓某些特定功能的程式如同板模般,當我們需要大量使用該功能時,直接由編譯器代為改變程式細節,以符合輸入的資料型態。 - PowerPoint PPT Presentation

Citation preview

Page 1: 第十五章

1

第十五章

樣板( Template )

Page 2: 第十五章

2

第十五章 樣板( Template )

• 樣板是 C++ 為了方便能夠快速生產程式而提供的新功能,在最初期的C++ 版本中,並不提供樣板機制。所謂樣板( Template ),就是讓某些特定功能的程式如同板模般,當我們需要大量使用該功能時,直接由編譯器代為改變程式細節,以符合輸入的資料型態。

• 因此,在現代化的程式設計中,大多將函式或類別設計為樣板,避免撰寫相同功能但資料型態不同的程式。在正式介紹樣板之前,請讀者注意一點,繼承與樣板都能增進程式碼重複使用率及減少程式開發時程,但樣板的對象是固定是類別和函式,而繼承僅限於類別,兩者在許多方面有根本上的不同。

Page 3: 第十五章

3

大綱

• 15.1 什麼是樣板 ?• 15.2 函式樣板

– 15.2.1 單一保留資訊的函式樣板– 15.2.2 多保留資訊的函式樣板

• 15.3 類別樣板• 15.4 樣板的具現• 15.5 本章回顧

Page 4: 第十五章

4

• 在 C 語言中,程式設計師常常會遇到一個麻煩的問題,就是即使函式需求相同,但必須針對不同資料型態,設計不同的函式,例如我們想要求出絕對值,就必須設計成兩個名稱不同的函式,如下範例。

15.1 什麼是樣板 ?

/************C 語言必須使用不同的函式名稱 *************/int i_abs(int X){ if (X<0) return -X; else return X;}double d_abs(double X){ if (X<0) return -X; else return X;}

Page 5: 第十五章

5

15.1 什麼是樣板 ?

– 在初期的 C++ 中,上述情況獲得改善,我們可以利用函式覆載 (Overload) 功能,將函式名稱設定為相同的 abs ,只要引數內容不同即可,如下範例。

– 雖然 C++ 提供了覆載函式來解決函式名稱的問題,但仍無法解決撰寫重複程式碼的問題(雖然通常只需要複製程式碼並略為修改即可),而後期的 C++ 則提供了樣板來解決上述問題。樣板允許保留一些資料,等到實際使用樣板時,才於編譯時期,由編譯器自行複製程式內容。

// ******** 初期的 C++ 可以使用覆載功解決函式名稱相同的問題 **********int abs(int X){ if (X<0) return -X; else return X;}double abs(double X){ if (X<0) return -X; else return X;}

Page 6: 第十五章

6

15.1 什麼是樣板 ?

• 事實上,樣板可分為兩大類:函式樣板 (Function Template)及類別樣板 (Class Template) ,而其目的則分別是為了加強的函式和類別的開發速度。有了樣板,我們只需預先設計一個通用的板模,然後當我們需要設計類似功能的函式或類別時,就套用這個樣板,並設定相關必要的資訊就可以了。

Page 7: 第十五章

7

15.1 什麼是樣板 ?

– 舉例來說,假設我們有一個交換函式 swap 函式如下,它可以作整數資料的交換。

– 在設計上述的 swap 函式樣板時,我們可以將程式碼內的 int 資料型態設定為保留資訊,當我們作整數交換時,只要套用這個樣板,並設定資料型態為 int ;當我們需要作字元交換,也是同樣可以套用這個樣板,只要將資料型態設定為 char 即可。換句話說,一個經過設計的樣板,可以讓我們節省很多撰寫類似程式碼的時間,因為編譯器將代為處理套用樣板時的函式轉換手續。

void swap( int *unit1 , int *unit2 ){

int temp ;temp = *unit1 ;*unit1 = *unit2 ;*unit2 = temp ;

}

Page 8: 第十五章

8

15.2 函式樣板

• C++ 的樣板有函式樣板與類別樣板兩種,我們先從簡單的函式樣板開始介紹,我們將函式樣板的宣告分為兩大類語法來加以介紹,即單一保留資訊的函式樣板與多保留資訊的函式樣板。

Page 9: 第十五章

9

15.2.1 單一保留資訊的函式樣板

• 單一保留資訊的函式樣板宣告與定義:– 單一保留資訊的函式樣板宣告語法如下:

– 單一保留資訊的函式樣板定義語法如下:

– 語法說明:• (1)N 是欲保留的資訊,也就是能被替換的資料型態,編譯器將依據呼叫時的資料型態,產生對應的變化。

• (2)class 關鍵字可改為 typename 。• (3) 函式回傳型態也可以宣告為 N (保留資訊)。

template <class N> 函式回傳型態 函式名稱 (N,N,...);

template <class N> 函式回傳型態 函式名稱 (N 引數 1,N 引數2,...){

... …樣板內容}

Page 10: 第十五章

10

15.2.1 單一保留資訊的函式樣板

• (4) 由於 C++ 是自由格式,因此常見到將宣告列改為兩行的格式,如下定義格式:

• 【觀念及實用範例 15-1 】:實作 swap 函式樣板,並在呼叫函式樣板時,傳入不同的資料型態。

• 範例 15-1: ch15_01.cpp (檔案位於隨書光碟 ch15\ch15_01.cpp )。

template <class N> 函式回傳型態 函式名稱 (N 引數 1,N 引數 2,...)

{... …樣板內容

}

Page 11: 第十五章

11

15.2.1 單一保留資訊的函式樣板

1234567891011121314151617181920

/******************************** 檔名 :ch15_01.cpp 功能 :swap()函式樣板化 ********************************/

#include <iostream>#include <stdlib.h>

using namespace std;

template <class T> void swap(T*,T*); //函式樣板的宣告 ,T為保留資料型態

template <class T>void swap(T* X,T* Y) //函式樣板的定義{ T temp; temp = *X; *X = *Y; *Y = temp;}

Page 12: 第十五章

12

2122232425262728293031323334353637 38 3940414243444546

int main(void){ char a1='i',b1='j'; int a2=25,b2=56; double a3=0.7,b3=9.3;

cout << "樣板 (套用 char資料型態 ):" << endl; cout << "a1 = "<< a1 <<" , b1 = " << b1 << endl; swap(&a1,&b1); cout << "Swap:" << endl; cout << "a1 = " << a1 <<" , b1 = " << b1 << endl; cout << "--------------------------" << endl; cout << "樣板 (套用 int資料型態 ):" << endl; cout << "a2 = " << a2 <<" , b2 = " << b2 << endl; swap(&a2,&b2); cout << "Swap:" << endl; cout << "a2 = " << a2 <<" , b2 = " << b2 << endl; cout << "--------------------------" << endl; cout << "樣板 (使用 double資料型態 ):" << endl; cout << "a3 = " << a3 <<" , b3 = " << b3 << endl; swap(&a3,&b3); cout << "Swap:" << endl; cout << "a3 = " << a3 <<" , b3 = " << b3 << endl; //system("pause"); return 0;}

Page 13: 第十五章

13

15.2.1 單一保留資訊的函式樣板

– 執行結果

– 範例說明:• (1)第 11 行,函式樣板宣告。第 13~20 行,函式樣板定義。對照上述範例,我們可以發現,定義中,僅將原本的 int 改寫為保留資訊 T 而已。

樣板 (套用 char資料型態 ):a1 = i , b1 = jSwap:a1 = j , b1 = i-------------------------樣板 (套用 int資料型態 ):a2 = 25 , b2 = 56Swap:a2 = 56 , b2 = 25-------------------------樣板 (使用 double資料型態 ):a3 = 0.7 , b3 = 9.3Swap:a3 = 9.3 , b3 = 0.7

Page 14: 第十五章

14

15.2.1 單一保留資訊的函式樣板

• (2) 當我們宣告 swap 為函式樣板後,每一次呼叫 swap 函式時,只要輸入正確的資料時,編譯器會先判斷是否為正確的指標或正確的資料型態,然後依照所判斷的資料型態自動產生相對應的程式碼。例如為了因應第 35 行的呼叫,編譯器會自動將樣板複製並取代保留資訊,成為下列程式碼:

void swap(int* X,int* Y){ int temp; temp = *X; *X = *Y; *Y = temp;}

Page 15: 第十五章

15

15.2.1 單一保留資訊的函式樣板

• (3) 當我們在呼叫函式樣板的時候,代入的引數會決定這個函式樣板的內部資料型態。因此在第 35 行,編譯器判斷及處理的流程如下圖。

圖 15-1 編譯器判斷及處理函式樣板的流程

Page 16: 第十五章

16

15.2.2 多保留資訊的函式樣板

• 有時候,我們想要保留的資訊不只一個的時候, C++ 仍允許我們建立樣板,只要將欲保留的資訊一一宣告即可,如下語法:

– 多保留資訊的函式樣板宣告語法如下:

– 多保留資訊的函式樣板定義語法如下:

– 語法說明:• (1)N1、 N2… 是欲保留的資訊,引數型態則可宣告為這些保留資訊的任一種。• (2)class 關鍵字可改為 typename 。• (3) 函式回傳型態也可以宣告為 N1或 N2……. (即保留資訊之一)。

template <class N1,class N2,……….> 函式回傳型態 函式名稱 (N1或 N2 …或 ,N1或 N2 …或 ,...);

template <class N1,class N2,………> 函式回傳型態 函式名稱 (N1或 N2 … 或 引數 1, N1或 N2 … 或 引數

2,..);{

... …樣板內容}

Page 17: 第十五章

17

15.2.2 多保留資訊的函式樣板

• (4) 假設我們有兩個保留資訊及兩個引數,則下列是一個合法的宣告範例:

• (5) 然而我們常常在使用函式樣板時,會不小心使用錯誤的語法,例如下列幾個錯誤範例:

template <class T1,class T2> void function(T1 a, T2 b);

typedef int T5; template <class T1, T2> void function1(T1 a, T2 b) ; //錯誤,因 T2前少了一個 class template <class T3 ,class T3> T3 function2(); //錯誤,因為兩個保留資訊採相同名稱template <class T4> void function3(T4 A,T4 B){ int T4; //錯誤,因 T4已經是保留資訊,不可在定義中宣告為變數 T4 temp; ………………..}template <class T5> void function4(T5 a); //錯誤,因為 T5已經被 typedef定義為 int

Page 18: 第十五章

18

15.2.2 多保留資訊的函式樣板

• 【觀念範例 15-2 】:函式樣板中包含多個保留資訊。• 範例 15-2: ch15_02.cpp (檔案位於隨書光碟 ch15\ch15_02.cpp )。

123456789101112131415161718192021

/******************************** 檔名 :ch15_02.cpp 功能 :函式樣板包含多筆保留資訊 ********************************/

#include <iostream>#include <stdlib.h>

using namespace std;

template <class T1,class T2> T1 power(T1,T2); //函式樣板的宣告

template <class T1,class T2>T1 power(T1 a,T2 b) //函式樣板的定義{ T1 result; result=1; for(T2 i=1;i<=b;i++) result=result*a; return result;}

Page 19: 第十五章

19

15.2.2 多保留資訊的函式樣板

– 執行結果

2223242526272829303132

int main(void){ int m=3,p=5; double n=1.5;

cout << "m= "<< m <<",p=" << p << ", m的 p次方 =" << power(m,p) << endl; cout << "n="<< n <<",p=" << p << ", n的 p次方 =" << power(n,p) << endl;

//system("pause"); return 0;} m= 3,p=5, m的 p次方 =243

n=1.5,p=5, n的 p次方 =7.59375

Page 20: 第十五章

20

15.2.2 多保留資訊的函式樣板

– 範例說明:• (1)第 11 行,函式樣板宣告。第 13~21 行,函式樣板定義。我們在樣板中保留了兩項資訊, T1與 T2 ,其中 T2 只用在引數宣告與函式定義,而 T1 則同時用在函式回傳值、引數宣告與函式定義。

• (2) 在第 27 行呼叫 power(m,p) 時,它將會建構下列的程式碼。

int power(int a,int b){ int result; result=1; for(int i=1;i<=b;i++) result=result*a; return result;}

Page 21: 第十五章

21

15.2.2 多保留資訊的函式樣板

• (3) 在第 28 行呼叫 power(n,p) 時,它將會建構下列的程式碼。

– 對於 T1 被引數及回傳值同時引用的部分,或許讀者會產生疑惑,在上述說明中,似乎編譯器只要確定引數的資料型態後,就決定了保留資訊應該被取代為哪一種資料型態。例如呼叫 power(m,p) 時, T1 被確認為 int ,在呼叫 power(n,p)時, T1 被確認為 double 。而若我們將回傳值使用另一種型態來接收時,例如int y=power(n,p); ,會是什麼樣的狀況呢?答案是會產生警告訊息,編譯器仍將T1 認為是 double ,因此回傳 double 資料型態的資料,當然最終結果 y 仍舊是被強制轉型的整數,在上例中, y 將會是 7 。

double power(double a,int b){ double result; result=1; for(int i=1;i<=b;i++) result=result*a; return result;}

Page 22: 第十五章

22

15.3 類別樣板

• 樣板除了可以應用於函式外,也可以應用於類別,這樣的類別稱之為『類別樣板』。經過樣板化的類別,其內的成員函式與成員變數可適用於所有的資料型態,只要將某些資訊宣告為保留資訊即可。類別樣板的宣告及定義與函式樣板大同小異,運作原理也差不多,如下所述。

• 首先讓我們先來看看類別樣板的標準宣告格式如下:– 類別樣板的定義語法如下:

template <class N> class 類別名稱{ 保護等級 : 函式回傳型態 函式名稱 (N 引數 1,N 引數 2,...); // 成員函式 ... N 變數名稱 ; // 成員變數 ...

}

Page 23: 第十五章

23

15.3 類別樣板

– 類別樣板的成員函式,若定義於類別外部,則語法如下:

– 類別樣板產生物件語法:

– 語法說明:• (1)N 是欲保留的資訊,如果保留資訊不只一個,也可以按照

<class N1,class N2,…> 等格式擴充。

類別樣板名稱 <保留資訊的資料型態 > 物件名稱 ;

template <class N> 函式回傳型態 類別樣板名稱 <N>::成員函式名稱 ( ){ …. 函式定義內容…}

Page 24: 第十五章

24

15.3 類別樣板

• (2)< > 內的 class 關鍵字可改為 typename 。• (3) 函式回傳型態也可以宣告為保留資訊之一。• (4) 宣告類別樣板內的成員函式,並在類別外部定義成員函式時,除了必須在前面加上 template <class N> ,原本的類別名稱,應該改為『類別樣板名稱 <N> 』。

• (5) 利用類別樣板產生物件時,也同樣必須加上保留資訊的資料型態,例如 <int>、 <float> 。

• (6) 常見的類別樣板宣告錯誤範例如下:• 錯誤範例

– 和函式樣板一樣的限制,類別樣板的引數型態定義不可以在類別中重複使用,如下例的 Type 。

Page 25: 第十五章

25

15.3 類別樣板

typedef int T3 ;template <class T1 , class T1 > class C1 // 錯誤,因為兩個保留資訊採相同名稱{ ….. };template <class T2> class C2{ …… private: int T2 ; // 錯誤,因 T2 已經是保留資訊,不可在定義中宣告為變數 ……};template <class T3> class C3 // 錯誤,因為 T3 已經被 typedef 定義為 int{ …… private: T3 item ; ……};

Page 26: 第十五章

26

15.3 類別樣板

• 【觀念及實用範例 15-3 】:使用類別樣板,使得氣泡排序法可以接受各種資料型態。

• 範例 15-3: ch15_03.cpp (檔案位於隨書光碟 ch15\ch15_03.cpp )。

12345678910

/******************************** 檔名 :ch15_03.cpp 功能 :類別樣板 ********************************/

#include <iostream>#include <stdlib.h>

using namespace std;

Page 27: 第十五章

27

111213141516171819202122232425262728293031323334353637

template <class T> class Sort; //類別樣板宣告

template <class T> class Sort //類別樣板定義{ public: Sort(int); //建構函式 void input(); //用於輸入陣列資料 void output(); //用於輸出陣列資料 void BubbleSort(); //用於將陣列資料排序 private: T* arr; //用於儲存資料的陣列起始位址 int arr_index; //陣列大小};

template <class T> Sort <T>::Sort(int x) //建構函式定義{ arr_index=x;}

template <class T> void Sort <T>::input() //成員函式定義{ for(int i=0;i<arr_index;i++) { cout << "請輸入第 " << i << "個元素 :"; cin >> arr[i]; }}

Page 28: 第十五章

28

38 39404142434445464748495051525354555657585960616263646566

template <class T> void Sort <T>::output() //成員函式定義{ for(int i=0;i<arr_index;i++) { cout << arr[i] << "\t"; } cout << endl;}template <class T> void Sort <T>::BubbleSort() //成員函式定義{ int k,times,i; T temp;

k=arr_index-1; while(k!=0) { times=0; for(i=0;i<=k-1;i++) { if(arr[i]>arr[i+1]) { temp=arr[i]; arr[i]=arr[i+1]; arr[i+1]=temp; //swap times=i; } } k=times; }}

Page 29: 第十五章

29

15.3 類別樣板

67686970717273747576777879808182838485868788

int main(void){ int qty=4; Sort <int> ObjX(qty); //透過類別樣板建立物件 ObjX cout << "----整數陣列已建立 ----" << endl; ObjX.input(); ObjX.output(); cout << "--------排序後 -------" << endl; ObjX.BubbleSort(); ObjX.output(); cout << "=========================" << endl; Sort <double> ObjY(qty); //透過類別樣板建立物件 ObjY cout << "----浮點數陣列已建立 ----" << endl; ObjY.input(); ObjY.output(); cout << "--------排序後 -------" << endl; ObjY.BubbleSort(); ObjY.output();

//system("pause"); return 0;}

Page 30: 第十五章

30

15.3 類別樣板

– 執行結果 ----整數陣列已建立 ----請輸入第 0個元素 :24請輸入第 1個元素 :17請輸入第 2個元素 :32請輸入第 3個元素 :1924 17 32 19--------排序後 -------17 19 24 32=========================----浮點數陣列已建立 ----請輸入第 0個元素 :15.67請輸入第 1個元素 :28.43請輸入第 2個元素 :17.52請輸入第 3個元素 :12.8815.67 28.43 17.52 12.88--------排序後 -------12.88 15.67 17.52 28.43

Page 31: 第十五章

31

15.3 類別樣板

– 範例說明:• (1)第 11 行,類別樣板宣告。第 13~23 行,類別樣板定義。我們在樣板宣告保留資訊為 T 。

• (2) 在第 70 行,類別樣板建立 ObjX 物件時, T 會被指定為 int 後,由編譯器產生對應的類別程式碼,然後才產生物件。

• (3) 在第 78 行,類別樣板建立 ObjY 物件時, T 會被指定為double 後,由編譯器產生對應的類別程式碼,然後才產生物件。

Page 32: 第十五章

32

15.4 樣板的具現

• 在上述的範例說明中,我們不斷地說明,當呼叫函式樣板時,或透過類別樣板宣告物件時,編譯器都會產生一些程式碼。事實上,這個由編譯器自動執行的動作稱之為『樣板的具現(instantiation) 』。– 在編譯時期,編譯器會將樣板依照所給予不同型別的引數,建構出對

應的函式或類別。若是經由函式呼叫而造成函式建構的動作,我們稱之為函式樣板的具現;而經過類別的生成物件而造成類別建構的動作,就稱為類別樣板的具現。函式樣板必須在具現後,才能被呼叫,而類別樣板則是必須在具現後,才能夠產生物件。

– 函式樣板的具現與類別樣板的具現可以是獨立的,但也可以有先後關係。這通常發生在類別樣板內又定義了成員函式樣板時。

Page 33: 第十五章

33

15.4 樣板的具現

• 雖然類別樣板已經能夠提高非常好的程式開發效率,但如果成員函式的相似性也很高,我們也可以利用函式樣板進一步定義類別樣板的成員函式,使得程式重複性更低。而此時,定義型態的過程將具有先後的關聯性。– 我們透過範例 15-4 ,說明編譯器對於樣板的定義流程。範例 15-4 ,將修改自

範例 15-3 ,將互換資料另外獨立出來成為 swap 成員函式,並使用函式樣板來宣告 swap 函式。

• 【觀念及實用範例 15-4 】:修改範例 15-4 ,結合類別樣板和函式樣板。• 範例 15-4: ch15_04.cpp (檔案位於隨書光碟 ch15\ch15_04.cpp )。

12345678910

/******************************** 檔名 :ch15_04.cpp 功能 :類別樣板內包含成員函式樣板 ********************************/

#include <iostream>#include <stdlib.h>

using namespace std;

Page 34: 第十五章

34

1112131415161718192021222324252627282930313233343536

template <class T> class Sort; //類別樣板宣告

template <class T> class Sort //類別樣板定義{ public: Sort(int); //建構函式 void input(); //用於輸入陣列資料 void output(); //用於輸出陣列資料 void BubbleSort(); //用於將陣列資料排序 template <class N1> void swap(N1* X,N1* Y) //成員函式樣板的宣告 { N1 temp; temp = *X; *X = *Y ; *Y = temp ; } private: T* arr; //用於儲存資料的陣列起始位址 int arr_index; //陣列大小};

template <class T> Sort <T>::Sort(int x) //建構函式定義{ arr_index=x;}

Page 35: 第十五章

35

15.4 樣板的具現

37 38 3940414243444546474849505152

template <class T> void Sort <T>::input() //成員函式定義{ for(int i=0;i<arr_index;i++) { cout << "請輸入第 " << i << "個元素 :"; cin >> arr[i]; }}template <class T> void Sort <T>::output() //成員函式定義{ for(int i=0;i<arr_index;i++) { cout << arr[i] << "\t"; } cout << endl;}

Page 36: 第十五章

36

15.4 樣板的具現

5354555657585960616263646566676869707172

template <class T> void Sort <T>::BubbleSort() //成員函式定義{ int k,times,i;

k=arr_index-1; while(k!=0) { times=0; for(i=0;i<=k-1;i++) { if(arr[i]>arr[i+1]) { swap(&(arr[i]),&(arr[i+1])); //呼叫 swap成員函式樣板 times=i; } } k=times; }}

Page 37: 第十五章

37

15.4 樣板的具現73747576777879808182838485868788899091929394

int main(void){ int qty=4; Sort <int> ObjX(qty); //透過類別樣板建立物件 ObjX cout << "----整數陣列已建立 ----" << endl; ObjX.input(); ObjX.output(); cout << "--------排序後 -------" << endl; ObjX.BubbleSort(); ObjX.output(); cout << "=========================" << endl; Sort <double> ObjY(qty); //透過類別樣板建立物件 ObjY cout << "----浮點數陣列已建立 ----" << endl; ObjY.input(); ObjY.output(); cout << "--------排序後 -------" << endl; ObjY.BubbleSort(); ObjY.output();

//system("pause"); return 0;}

Page 38: 第十五章

38

15.4 樣板的具現– 執行結果:(同範例 15-3 )– 範例說明:

• 在類別樣板內,我們又宣告了一個成員函式樣板 swap (在第20~26 行)。並且在 BubbleSort 成員函式的第 65 行呼叫這個成員函式。整個編譯器在編譯過程如下:

– Step1: 在第 76 行,遇到 Sort <int> ObjX; ,先決定保留資訊T 的資料型態為 int 。

– Step2: 此時 T 變成了輸入引數資料型態為 int的 Sort 類別,也就是必須將 T 替換為 int 產生類別的程式碼。

– Step3: 但編譯器欲產生類別的程式碼時,發現定義了一個成員函式樣板,因此,編譯器必須保留該位置,等到決定BubbleSort 成員函式的內容時,找到 swap 函式樣板的呼叫時,才產生 swap 函式的程式碼,完成 swap 函式的具現後,才能夠完成 Sort 類別的具現。換句話說,具現的過程有如一個堆疊(先進後出),當遇到另一個更深層的具現時,則必須將更深層具現完成後,才能完成較外圍的具現。

Page 39: 第十五章

39

15.5 本章回顧

• 在本章中,我們介紹了 C++ 提供的新功能-『樣板』,善用樣板可以讓我們更有效率地開發中大型專案,減少撰寫相似程式碼的機會,本章重點整理如下:– (1)C++ 提供了樣板來解決相似程式碼浪費開發時程的問題。樣板允許保留一

些資料,等到實際使用樣板時,才於編譯時期,由編譯器自行複製程式內容。– (2) 樣板可分為兩大類:函式樣板 (Function Template) 及類別樣板 (Class

Template) 。兩者運作的方式和觀念差不多。– (3) 函式樣板的語法如下:

• 單一保留資訊的函式樣板宣告語法如下:

• 單一保留資訊的函式樣板定義語法如下:template <class N> 函式回傳型態 函式名稱 (N,N,...);

template <class N> 函式回傳型態 函式名稱 (N 引數 1,N 引數 2,...){

...樣板內容…}

Page 40: 第十五章

40

15.5 本章回顧

• 多保留資訊的函式樣板宣告語法如下:

• 多保留資訊的函式樣板定義語法如下:

template <class N1,class N2,……….>函式回傳型態 函式名稱 (N1或 N2或… ,N1或 N2或… ,...);

template <class N1,class N2,………>函式回傳型態 函式名稱 (N1或 N2或… . 引數 1, N1或 N2或… . 引數 2,...);{

...樣板內容…}

Page 41: 第十五章

41

15.5 本章回顧

– (4) 類別樣板的相關語法如下:• 類別樣板的定義語法如下:

• 類別樣板的成員函式,若定義於類別外部,則語法如下:

template <class N> class 類別名稱{ 保護等級 : 函式回傳型態 函式名稱 (N 引數 1,N 引數 2,...); // 成員函式 ... N 變數名稱 ; // 成員變數 ...

}

template <class N> 函式回傳型態 類別樣板名稱 <N>::成員函式名稱 ( ){ ….函式定義內容…}

Page 42: 第十五章

42

15.5 本章回顧

• 類別樣板產生物件語法:

– (5) 在編譯時期,編譯器會將樣板依照所給予不同型別的引數,建構出對應的函式或類別,這個由編譯器自動執行的動作稱之為『樣板的具現 (instantiation) 』。發生的時機則發生於函式樣板的呼叫以及類別樣板產生物件時。

– (6) 在類別樣板內也可以再定義成員函式的樣板。

類別樣板名稱 <保留資訊的資料型態 > 物件名稱 ;

Page 43: 第十五章

43

本章習題