1. 程式人生 > >C++泛型程式設計:函式模板與類模板

C++泛型程式設計:函式模板與類模板

泛型程式設計是一種語言機制,通過他可以實現一個標準的容器庫,可以處理不同的資料型別.
比如對棧的描述:
class stack
{
push(引數型別)//入棧
pop(引數型別)//出棧
}
由於上面的程式碼與資料型別有關,可以通過模板實現一個程式碼處理不同的資料型別。
首先執行一種通用的資料型別,不用具體指明哪一種。
class stack<引數模板 T>
{
push(T)//入棧
pop(T)//出棧
}
這裡的引數模板T相當於一個佔位符,當我們例項化類stack時,T會被具體的資料型別替換掉。

泛型在C++中的應用

泛型在C++中的主要實現為模板函式和模板類。
通常使用普通的函式實現一個與資料型別有關的演算法是很繁瑣的,比如兩個數的加法:

int add(int a,int b) { return a+b; }
float add(float a,float b) { return  a+b; }

雖然在C++中可以通過函式過載來解決這個問題,但是函式過載是靜態編譯,執行時佔用過多記憶體。
在此我們可以用C++的模板函式來表達通用型的函式,如下:

template<typename T> // 模板宣告
T add(T a,T b) { return a+b; }  // 注意形參和返回值的型別

這時C++編譯器會根據add函式的引數型別來生成一個與之對應的帶具體引數型別的函式並呼叫。

#include
<iostream>
using namespace std; template <typename T> T add(T a,T b) //注意形參和返回型別 { return a+b; } void main() { int num1, num2, sum; cin>>num1>>num2; sum=add(num1,num2); //用int匹配模版引數T,若sum,num1,num2型別不一致則無法匹配。 cout<<sum; }

函式模板的寫法

template <typename 模板引數列表>
函式返回型別 函式名(形參列表)
關鍵字template 和typename是必須的,typename可以使用關鍵詞class替換

  • 模板並不建立任何函式,而是告訴編譯器如何定義函式。
  • 函式模板不允許自動型別轉換。
  • 函式模板不可以設定預設模板實參。比如template 不可以。
  • 函式模板也可以向函式一樣進行過載。

類模板的寫法

//類宣告部分,有兩個模板引數T1,T2
template  <class T1, class T2 >  
class A {
   private:
   int a;
  T1 b;  //成員變數也可以用模板引數
  public: 
  int fun1(T1 x, int y );
 T2 fun2(T1 x, T2 y);
}
//類實現部分
template  <class T1, class T2 >
int A<T1>:: fun1(T1 x, int y ){//實現…… }
 template  <class T1, class T2 >
T2 A<T1,T2>:: fun2(T1 x, T2 y) {//實現…… }
 //使用類A
 int main( ) {
 //定義物件a,並用int替換T1, float替換T2
   A<int, float>  a;
   //例項化a,呼叫a的屬性和方法……
}

由上例可以看出, 類模板引數T1,T2對類的成員變數和成員函式均有效。
在C++程式設計中,當你要實現的一個類的某些成員函式和成員變數的演算法跟資料型別有關,可以考慮用類模板,且C++版的資料結構演算法大都用類模板實現。