若一個程序的功能是對某種特定的數(shù)據(jù)類型進行處理,則將所處理的數(shù)據(jù)類型說明為參數(shù),就可以把這個程序改寫為模板。 C++ 程序由類和函數(shù)組成,所以 C++ 的模板也分為類模板和函數(shù)模板。
1、 函數(shù)模板的定義:
• 函數(shù)模板的一般定義形式:
template < 類型形式參數(shù)表 > 返回類型 FunctionName( 形式參數(shù)表 )
{
// 函數(shù)定義體
}
• 說明:⒈ < 類型形式參數(shù)表 > 可以包含基本數(shù)據(jù)類型,也可以包含類類型。若是類類型,則須加前綴 class 。
⒉這樣的函數(shù)模板定義不是一個實實在在的函數(shù),編譯系統(tǒng)不為其產(chǎn)生任何執(zhí)行代碼。該定義只是對函數(shù)的描述,表示它每次能單獨處理在類型形式參數(shù)表中說明的數(shù)據(jù)類型。
⒊當(dāng)編譯系統(tǒng)發(fā)現(xiàn)有一個函數(shù)調(diào)用: FunctionName( 實在參數(shù)表 ); 將根據(jù)實在參數(shù)表中的類型,確認是否匹配函數(shù)模板中對應(yīng)的形式參數(shù)表,然后生成一個重載函數(shù)。該重載函數(shù)的定義體和函數(shù)模板的函數(shù)定義體相同,而形式參數(shù)表的類型則以實在參數(shù)表的實際類型為依據(jù)。該重載函數(shù)稱為模板函數(shù)。
• 函數(shù)模板與模板函數(shù)的區(qū)別:
函數(shù)模板是模板的定義,定義中用到通用類型參數(shù)。
模板函數(shù)是實實在在的函數(shù)定義,它由編譯系統(tǒng)在碰見具體的函數(shù)調(diào)用時所生成,具有程序代碼。
例 1 : #include
template T Max(T&a,T&b)
T max(T a,T b)
{
return a>b?a:b;
}
void main()
{
cout<<”Max(3,5) is”< cout<<”Max(‘ 3' ,' 5' ) is:< }
運行結(jié)果為: Max(3,5) is 5
Max(‘ 3' ,' 5' ) is 5
分析:當(dāng)編譯程序發(fā)現(xiàn) Max(3,5) 調(diào)用時,它就產(chǎn)生一個如下一個函數(shù)定義,生成其程序代碼:
int Max(int a,int b)
{
return a>b?a:b;
}
當(dāng)發(fā)現(xiàn) Max(‘ 3' ,' 5' ) 調(diào)用時,它又產(chǎn)生另一個如下的函數(shù)定義,也生成其程序代碼:
char Max(char a,char b)
{
return a>b?a:b;
}
這樣實參是什么數(shù)據(jù)類型,返回值也是什么類型,避免了相同操作的重載定義。
另外可以象重載普通函數(shù)那樣重載模板函數(shù)。
例 2 : #include
#include
template T max(T a,T b)
{
return a>b?a:b;
}
char *max(char *a,char *b)
{
return (strcmp(a,b)?a:b);
}
void main()
{
cout<<”Max(\”hello\”,\”gold\” is “< }
函數(shù) char *max(char *,char *) 中的名字 max 與函數(shù)模板的名字相同,但操作不同,這種情況就是重載模板函數(shù)。編譯程序在處理這種情況時,首先匹配重載函數(shù),然后再尋求模板的匹配。該程序中, max(“hello”,”gold”) 調(diào)用,匹配了非模板函數(shù) char *(char *,char *) 。
2、類模板的定義:
• 類模板的一般定義形式:
template< 類型形式參數(shù)表 > class classname
{
// 類聲明體
}
template < 類型形式參數(shù)表 > 返回類型 classname< 類型名表 >::MemberFunctionname1( 形式參數(shù)表 )
{
// 成員函數(shù)定義體
}
template < 類型形式參數(shù)表 > 返回類型 classname< 類型名表 >::MemberFunctionname2( 形式參數(shù)表 )
{
// 成員函數(shù)定義體
}
template < 類型形式參數(shù)表 > 返回類型 classname< 類型名表 >::MemberFunctionnamen( 形式參數(shù)表 )
{
// 成員函數(shù)定義體
}
• 說明:⒈其中的類型形式參數(shù)表與函數(shù)模板中的意義一樣。后面的成員函數(shù)定義中, classname< 類型名表 > 中的類型名表是類型形式參數(shù)的使用。
⒉這種類模板的定義其實只是對類的描述,不是具體的類。
⒊建立類模板后,可以通過創(chuàng)建類模板的實例來使用該類模板。
Classname < 類型實在參數(shù)表 > object;
• 類模板與模板類的區(qū)別:
類模板是模板的定義,不是一個實在的類, 定義中用到通用類型參數(shù)。
模板類是實在的類定義,是類模板的實例化。類定義中參數(shù)被實際類型所代替。
例 3 :定義一個單向鏈表的模板類,它分別實現(xiàn)增加、刪除、尋找和打印操作。
#include
templateclass List
{
public:
List();
Void Add(T&);
Void Remove(T&);
T* Find(T&);
Void printList();
~List();
private:
struct Node{
Node *pNext;
T *pT;
};
Node *pFirst;
}
template List ::List()
{
pFirst=0;
}
template void List::Add(T&t)
{
node *temp=new Node;
temp->pT=&t;
temp->pNext=pFirst;
pFirst=temp;
}
1、 函數(shù)模板的定義:
• 函數(shù)模板的一般定義形式:
template < 類型形式參數(shù)表 > 返回類型 FunctionName( 形式參數(shù)表 )
{
// 函數(shù)定義體
}
• 說明:⒈ < 類型形式參數(shù)表 > 可以包含基本數(shù)據(jù)類型,也可以包含類類型。若是類類型,則須加前綴 class 。
⒉這樣的函數(shù)模板定義不是一個實實在在的函數(shù),編譯系統(tǒng)不為其產(chǎn)生任何執(zhí)行代碼。該定義只是對函數(shù)的描述,表示它每次能單獨處理在類型形式參數(shù)表中說明的數(shù)據(jù)類型。
⒊當(dāng)編譯系統(tǒng)發(fā)現(xiàn)有一個函數(shù)調(diào)用: FunctionName( 實在參數(shù)表 ); 將根據(jù)實在參數(shù)表中的類型,確認是否匹配函數(shù)模板中對應(yīng)的形式參數(shù)表,然后生成一個重載函數(shù)。該重載函數(shù)的定義體和函數(shù)模板的函數(shù)定義體相同,而形式參數(shù)表的類型則以實在參數(shù)表的實際類型為依據(jù)。該重載函數(shù)稱為模板函數(shù)。
• 函數(shù)模板與模板函數(shù)的區(qū)別:
函數(shù)模板是模板的定義,定義中用到通用類型參數(shù)。
模板函數(shù)是實實在在的函數(shù)定義,它由編譯系統(tǒng)在碰見具體的函數(shù)調(diào)用時所生成,具有程序代碼。
例 1 : #include
template
T max(T a,T b)
{
return a>b?a:b;
}
void main()
{
cout<<”Max(3,5) is”<
運行結(jié)果為: Max(3,5) is 5
Max(‘ 3' ,' 5' ) is 5
分析:當(dāng)編譯程序發(fā)現(xiàn) Max(3,5) 調(diào)用時,它就產(chǎn)生一個如下一個函數(shù)定義,生成其程序代碼:
int Max(int a,int b)
{
return a>b?a:b;
}
當(dāng)發(fā)現(xiàn) Max(‘ 3' ,' 5' ) 調(diào)用時,它又產(chǎn)生另一個如下的函數(shù)定義,也生成其程序代碼:
char Max(char a,char b)
{
return a>b?a:b;
}
這樣實參是什么數(shù)據(jù)類型,返回值也是什么類型,避免了相同操作的重載定義。
另外可以象重載普通函數(shù)那樣重載模板函數(shù)。
例 2 : #include
#include
template
{
return a>b?a:b;
}
char *max(char *a,char *b)
{
return (strcmp(a,b)?a:b);
}
void main()
{
cout<<”Max(\”hello\”,\”gold\” is “<
函數(shù) char *max(char *,char *) 中的名字 max 與函數(shù)模板的名字相同,但操作不同,這種情況就是重載模板函數(shù)。編譯程序在處理這種情況時,首先匹配重載函數(shù),然后再尋求模板的匹配。該程序中, max(“hello”,”gold”) 調(diào)用,匹配了非模板函數(shù) char *(char *,char *) 。
2、類模板的定義:
• 類模板的一般定義形式:
template< 類型形式參數(shù)表 > class classname
{
// 類聲明體
}
template < 類型形式參數(shù)表 > 返回類型 classname< 類型名表 >::MemberFunctionname1( 形式參數(shù)表 )
{
// 成員函數(shù)定義體
}
template < 類型形式參數(shù)表 > 返回類型 classname< 類型名表 >::MemberFunctionname2( 形式參數(shù)表 )
{
// 成員函數(shù)定義體
}
template < 類型形式參數(shù)表 > 返回類型 classname< 類型名表 >::MemberFunctionnamen( 形式參數(shù)表 )
{
// 成員函數(shù)定義體
}
• 說明:⒈其中的類型形式參數(shù)表與函數(shù)模板中的意義一樣。后面的成員函數(shù)定義中, classname< 類型名表 > 中的類型名表是類型形式參數(shù)的使用。
⒉這種類模板的定義其實只是對類的描述,不是具體的類。
⒊建立類模板后,可以通過創(chuàng)建類模板的實例來使用該類模板。
Classname < 類型實在參數(shù)表 > object;
• 類模板與模板類的區(qū)別:
類模板是模板的定義,不是一個實在的類, 定義中用到通用類型參數(shù)。
模板類是實在的類定義,是類模板的實例化。類定義中參數(shù)被實際類型所代替。
例 3 :定義一個單向鏈表的模板類,它分別實現(xiàn)增加、刪除、尋找和打印操作。
#include
template
{
public:
List();
Void Add(T&);
Void Remove(T&);
T* Find(T&);
Void printList();
~List();
private:
struct Node{
Node *pNext;
T *pT;
};
Node *pFirst;
}
template
{
pFirst=0;
}
template
{
node *temp=new Node;
temp->pT=&t;
temp->pNext=pFirst;
pFirst=temp;
}