C++|泛化數據類型:模板與泛型編程

數據結構 技術 小智雅匯 2017-06-08

1 泛型思維

我們在解決一些特殊問題的時候,常常會將其中的某些因素或結構泛化推廣到一般的情況,然後找到求解此類問題的一般化方法,即從特殊到一般的歸納思維;而對於特殊問題求解,則只需指定其具體的因素或結構形式,然後藉助一般化方法進行求解,即從一般到特殊的演繹思維。泛型思維,本質上是這種先歸納後演繹的思維。

所謂泛型,字面含義是泛類型化或類型泛化,也就是把函數或者類中的數據類型或者對象類型單獨提取出來作為一個參變量對待,從而使函數或者類具有更強的通用性。利用泛型思維編寫程序描述問題求解思路,即泛型編程(Generic Programming),需要做歸納方向的泛化描述和演繹方向的具象應用兩件事情:

1.1 泛化描述:在數據類型參數泛化的前提下描述通用的問題求解思路;

1.2 具體化應用:在通用問題求解思路的基礎上指定具體的數據類型,從而產生具體問題的求解思路,然後,使用具體問題求解思路實現問題求解。

此外,C++語言基於模板機制實現了常用的一些算法和數據結構,形成了一個具有工業級強度、健壯可靠的泛型程序庫,稱為標準模板庫(Standard Template Libarary), 是我們進行泛型編程最可依賴的基礎。

2 數據類型泛化:定義模板

C++支持泛型編程,它提供了模板機制來支持數據參數泛化,包括函數模板和類模板,其中函數模板用於支持過程化問題求解思路的泛化,類模板用於支持面向對象問題求解思路的泛化。

根據模板產生一個具體函數和類的過程,稱們稱為模板實例化或者具像化。

2.1 函數模板

如有以下三個函數:

int sum(int a,int b);

double sum(double a,double b);

float sum(float a,float b);

不難看出,這三個sum函數具有一個統一的模式:

類型 sum(a 類型, b 類型);

如果將這個統一模式中的數據類型提取出來作為一個可變參數,則我們就不需要為每種數據類型重載一個sum函數,而只需要定義如下一個函數模板:

template<typename T> //告訴編譯器,T是一個數據類型參數

T sum (T a, T b) { return a+b; }

有了模板函數,便可以實例化一個具體的函數:

int sum (int a, int b) { return a+b; }

函數模板定義與實例化可用一個實例來進行說明:

#include <stdio.h>

#include <conio.h>

template<typename T>

T max(const T arr[], int size) {

T maxElem=arr[0];

for (int i=0;i<size;i++)

if(arr[i]>maxElem) maxElem=arr[i];

return maxElem;

}

int main(){

int a[] = {1,2,4,8,7};

int b = max(a, sizeof(a)/sizeof(int));

printf("最大數組元素:%d",b);

getch();

return 0;

}

//函數模板也可顯示實例化:template int max<int>(const int[],int);

運算結果:

最大數組元素:8

2.2 類模板

與函數模板類似,很多時候兩個類或者多個類功能相同而數據類型有區別,此時就可以通過類模板把這些類的類型參數泛化,建立統一的類描述。語法如下:

template<class T, ... , int size, ...)

class Array {...}

如有類模板定義:

template<class T=int)

class Array {...}

有了類模板定義,然後可以隱式實例化一個具體的類:

Array<double>doubleArr(10);

或者顯式實例化:

template class Array<double>;

應該可以這樣說,泛化數據類型是數據類型從基本數據類型到結構體類型再到類類型的另一個層面的抽象;而泛型編程思維是相對於面向過程、面向對象的更高層面的一種抽象。

相關推薦

推薦中...