1、基本概念
所謂泛型編程:以獨立於任何特定類型的方式編寫代碼。使用泛型程序時,我們需要提供具體程序實例所操作的類型或值。標准庫的容器、迭代器和算法都是泛型編程的例子。每種容器如:vector)都有單一的定義,但可以支持定義許多不同種類的vector,他們的區別在於所包含的元素類型。
模板是泛型編程的基礎。
泛型編程與面向對象編程一樣,都依賴於某種形式的多態性,面向對象編程依賴的多態性稱為運行時多態性,泛型編程依賴的多態性稱為編譯時多態性或參數多態性。對於運行時多態性,只要使用基類的引用或指針,基類類型或派生類類型的對象就可以使用相同的代碼。在泛型編程中,我們所編寫的函數和類能夠多態的用於跨越編譯時不相關的類型。一個類和一個函數可以用來操縱多種類型的對象。
在C++中,模板是泛型編程的基礎,模板是創建類或函數的藍圖或公式。如標准庫定義了一個類模板vector,可以產生任意數量的特定類型的vector類,如vector<int>和vector<string>。
2、模板定義
1.舉例
1)int compare(const string &v1, const string &v2)
{
if(v1<v2) return -1;
if(v2<v1) return 1;
return 0;
}
2)int compare(const int &v1, const int &v2)
{
if(v1<v2) return -1;
if(v2<v1) return 1;
return 0;
}
(3) int compare(const double &v1, const double &v2)
{
if(v1<v2) return -1;
if(v2<v1) return 1;
return 0;
}
我們可以用函數重載來實現不同類型的比較,但是觀察可知,上述3個函數只有形參不同,函數體是相同的,我們可以用函數模板來實現任意類型數據的比較。不僅僅是3種類型,如果希望此函數用於未知類型,只能用函數模板了。
2、函數模板定義
函數模板是一個獨立於類型的額函數,可作為一種方式,產生特定的函數版本。
template <typename T>
int compare(const T &v1, const T &v2)
{
if(v1<v2) return -1;
if(v2<v1) return 1;
return 0;
}
模板定義以關鍵字template開始,後接模板形參表,模板形參表是用尖括號擴住的一個或多個模板形參的列表,形參之間以逗號分隔。
模板形參表不能為空。
3 模板形參表
模板形參可以是表示類型的類型形參,也可以是表示常量表達式的非類型形參。
類型形參在關鍵字class或typename後面定義。非類型形參在類型說明符之後聲明。
其中,在此,關鍵字class和typename沒有區別。
4 使用函數模板
使用函數模板時,編譯器會推斷那個模板實參綁定到形參,一旦編譯器確定了實際的模板實參,就稱它例化了函數模板的一個實例。
用實參的類型推斷出類型形參的類型。
如int a = 10; int b= 11;
compare(a, b);
變量a時int型,推出形參const T &v1中的T為int型,同理得到const T &v2中的形參為int。然後根據函數形參的類型推斷出模板形參的類型,對應的typename T 中的T為int,然後把模板函數中所有的T都換做int。稱為實例化了函數模板的一個實例。
5、 inline 函數模板
inline關鍵字要在模板形參表之後,返回類型之前,不能放在關鍵字template之前。如:
template <typename T> inline T min(const T&, const T&);
3、定義類模板
舉個例子:
template <typename Type> class Queue
{
public:
Queue();
Type &front();
const Type &front() const;
void push(const Type &);
void pop();
bool empty() const;
private:
//.....
};
//成員函數的實現
template <typename Type> void Queue<Type>::push(const Type &v1)
{
//....
}
總結:
函數模板是建立算法庫的基礎。類模板是簡歷標准庫容器和迭代器類型的基礎。
模板和虛函數應該是不能摻雜在一起的。
本文出自 “李海川” 博客,請務必保留此出處http://lihaichuan.blog.51cto.com/498079/1291948