函式樣板
函数模板的声明形式如下:
template <class identifier> function_declaration;
template <typename identifier> function_declaration;
template < 樣板參數型態 樣板參數名 , …其他樣板參數 >
原型回傳型態 函式名稱(參數型態 原型參數名, ...)
{
程式碼;
}
函式樣板:參數型態可用關鍵字 class
或 typename
表示泛用型態 (即任何型態);或是一個已宣告的資料型態,如int 與自定類。
原型中的參數型態若是已宣告的資料型態,則是一種特殊化的函式樣板。
#include <iostream>
using namespace std;
int Add(int a, int b)
{
return a + b;
}
template <class T>
T Add(T a, T b)
{
return a + b;
}
int main()
{
int c1;
double c2;
c1 = Add(10, 20);
c2 = Add(10.3, 20.4);
return 0;
}
C++函式樣板寫一個泡沫排序法(BubbleSort):
#include <iostream>
#include <string>
using namespace std;
template <class T>
void BubbleSort(int n, T A[])
{
T temp;
int i, j;
for (i = n - 1; i>1; i--) //for(i=0; i<n-1; i++)
{
for (j = 0; j<i; j++) //for(j=0; j<n-1; j++)
{
if (A[j] > A[j + 1])
{
temp = A[j];
A[j] = A[j + 1];
A[j + 1] = temp;
}
}
}
}
template <class T>
void PrintArray(int n, T A[])
{
int i;
for (i = 0; i<n; i++)
cout << A[i] << " ";
cout << endl;
}
int main()
{
int n = 5;
int A1[5] = { 12,33,2,4,22 };
double A2[5] = { 12.43, 12.33, 2.4 ,4.66 ,22.1 };
char A3[5] = { 'G','B','H','Z','Q' };
string A4[5] = { "Joe", "John", "Andy", "Mary", "Bob" };
BubbleSort(n, A1);
BubbleSort(n, A2);
BubbleSort(n, A3);
BubbleSort(n, A4);
PrintArray(n, A1);
PrintArray(n, A2);
PrintArray(n, A3);
PrintArray(n, A4);
system("pause");
return 0;
}
输出:
2 4 12 22 33
2.4 4.66 12.33 12.43 22.1
B G H Q Z
Andy Bob Joe John Mary
请按任意键继续. . .
類別樣板
template < 樣板參數型態 樣板參數名 , … >
class 類別名稱<部份特殊化型態,…>
{
原型回傳型態 函式名稱(參數型態 原型參數名, ...) ;
參數型態 變數名稱;
}
template < 樣板參數型態 樣板參數名 , … >
原型回傳型態 類別名稱< 樣板參數型態 樣板參數名 , … > ::函式名稱<部份特殊化型態,…>
{
程式碼;
}
類別名稱
例子:
#include <iostream>
#include <string>
using namespace std;
class myClass
{
public:
void display(int n)
{
a = n;
cout << a << endl;
}
int a;
};
template <class T>
class myTClass
{
public:
void display(T n)
{
a = n;
cout << a << endl;
}
T a;
};
int main()
{
myTClass<int> a;
myTClass<double> x;
a.display(10);
x.display(10.4);
return 0;
}
例子2:
#include <iostream>
#include <string>
using namespace std;
class myClass
{
public:
void display(int n, char ch)
{
a = n;
b = ch;
cout << a << " " << b << endl;
}
int a;
char b;
};
template <class T1, class T2>
class myTClass
{
public:
void display(T1 n, T2 ch)
{
a = n;
b = ch;
cout << a << " " << b << endl;
}
T1 a;
T2 b;
};
int main()
{
myTClass<int, char> a;
myTClass<double, double> x;
a.display(10, 'A');
x.display(10.4, 20.5);
return 0;
}
使用鏈結串列範例為例, 製作鏈結串列樣板:
// 永远.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <numeric> // Need accumulate()
#include <iostream>
#include <string>
#include <conio.h>
#include <stdlib.h>
using namespace std;
template <class T>
class node
{
public:
T data;
node<T> *next;
};
template <class T>
class LinkedList
{
public:
LinkedList();
void insert(T &value);
void remove(T &value);
void find(T &value);
void print();
private:
node<T> *getnode();
void freenode(node<T> *p);
void insert_node(node<T> *ptr, T &value);
void delete_node(node<T> *ptr);
node<T> *find_node(T &num);
int length();
node<T> *head;
node<T> *tail;
};
template <class T>
LinkedList<T>::LinkedList()
{
head = NULL;
tail = NULL;
}
template <class T>
node<T> *LinkedList<T>::getnode() /* 此函數產生一個新節點 */
{
node<T> *p;
p = new node<T>;
if (p == NULL)
{
cout << "記憶體不足" << endl;
exit(1);
}
return(p);
}
template <class T>
void LinkedList<T>::freenode(node<T> *p) /* 此函數將節點還給記憶體 */
{
delete p;
}
template <class T>
void LinkedList<T>::insert_node(node<T> *ptr, T &value)
{
node<T> *new_node; /* 新節點指標變數 */
new_node = getnode(); /* 建立新節點,取得一個可用節點 */
new_node->data = value; /* 建立節點內容 */
new_node->next = NULL; /* 設定指標初值 */
if (ptr == NULL) /* 指標ptr是否是NULL */
{
/* 第一種情況: 插入第一個節點 */
new_node->next = head; /* 新節點成為串列開始 */
head = new_node;
}
else
{
if (ptr->next == NULL) /* 是否是串列結束 */
/* 第二種情況: 插入最後一個節點 */
ptr->next = new_node; /* 最後指向新節點 */
else
{
/* 第三種情況: 插入成為中間節點 */
new_node->next = ptr->next; /* (3) 新節點指向下一節點 (3)*/
ptr->next = new_node; /* 節點ptr指向新節點 (4)*/
}
}
}
template <class T>
void LinkedList<T>::delete_node(node<T> *ptr)
{
node<T> *previous; /* 指向前一節點 */
if (ptr == head) /* 是否是串列開始 */
/* 第一種情況: 刪除第一個節點 */
{
head = head->next;
}
else
{
previous = head;
while (previous->next != ptr) /* 找節點ptr的前節點 */
previous = previous->next;
if (ptr->next == NULL) /* 是否是串列結束 */
/* 第二種情況: 刪除最後一個節點 */
previous->next = NULL; /* 最後一個節點 */
else
/* 第三種情況: 刪除中間節點 */
previous->next = ptr->next; /* 圖(3)之步驟(1) */
}
freenode(ptr); /* 此函數將節點歸還給記憶體 */
}
template <class T>
node<T> *LinkedList<T>::find_node(T &num)
{
node<T> *ptr;
ptr = head; /* 指向串列起始 */
while (ptr != NULL) /* 走訪串列 */
{
if (ptr->data == num) /* 找尋data */
return (ptr);
ptr = ptr->next; /* 指向下一節點 */
}
return (ptr);
}
template <class T>
int LinkedList<T>::length() /* 此函數計算節點之鏈結長度 */
{
int num = 0;
node<T> *q = head;
while (q != NULL)
{
num++;
q = q->next;
}
return(num);
}
template <class T>
void LinkedList<T>::insert(T &value)
{
if (head == NULL)
{
head = getnode();
head->data = value;
head->next = NULL;
tail = head;
}
else
{
insert_node(tail, value);
tail = tail->next;
}
cout << "資料插入成功!" << endl;
}
template <class T>
void LinkedList<T>::remove(T &value)
{
node<T> *prev, *ptr;
ptr = find_node(value);
if (ptr != NULL)
{
if (length() == 1)
{
delete_node(ptr);
tail = NULL;
}
else if (ptr->next == NULL)
{
prev = head;
while (prev->next != ptr)
prev = prev->next;
delete_node(ptr);
tail = prev;
}
else
{
delete_node(ptr);
}
cout << "資料已刪除!" << endl;
}
else
{
cout << "無此資料!" << endl;
}
}
template <class T>
void LinkedList<T>::find(T &value)
{
node<T> *ptr;
ptr = find_node(value);
if (ptr != NULL)
{
cout << "找到節點資料: " << ptr->data << endl;
}
else
{
cout << "找不到該節點資料" << endl;
}
}
template <class T>
void LinkedList<T>::print()
{
node<T> *q = head;
while (q != NULL)
{
cout << q->data << " ";
q = q->next;
}
cout << endl;
}
int main()
{
LinkedList<int> list;
int value;
char key;
while (1)
{
cout << "i: 插入" << endl;
cout << "d: 刪除" << endl;
cout << "f: 尋找" << endl;
cout << "l: 列印" << endl;
cout << "e: 離開" << endl;
cout << "> ";
key = _getche();
cout << endl;
switch (key)
{
case 'i':
cout << "輸入插入資料內容: ";
cin >> value;
list.insert(value);
break;
case 'd':
cout << "輸入刪除資料內容: ";
cin >> value;
list.remove(value);
break;
case 'f':
cout << "輸入尋找資料內容: ";
cin >> value;
list.find(value);
break;
case 'l':
list.print();
break;
case 'e':
cout << "ByeBye!" << endl;
exit(0);
default:
cout << "輸入值錯誤!" << endl;
}
cout << endl;
}
return 0;
}
参考:
http://homepage.ntu.edu.tw/~d02922022/AdvC/ppt/Part%202/08%20C++%E6%A8%A3%E6%9D%BF(Template).pdf