C++——模板

audience_fzn發表於2018-08-08

概念:

模板是泛型程式設計的基礎,所謂泛型程式設計就是編寫與型別無關的邏輯程式碼,是一種複用的方式。模板將型別定義為引數,從而實現了真正的程式碼可採用性

模板分為模板函式和模板類

一、模板函式

假設現在要實現一個比較倆個數是否相等的過載函式

int IsEqual(int a, int b)
{
	return a == b;
}
bool IsEqual(const string& left, const string& right)
{
	return left == right;
}
void Test()
{
	string s1("s1"), s2("s2");
	cout << IsEqual(s1, s2) << endl;
	cout << IsEqual(1, 1) << endl;
}

如果還想實現char型別,double型別的比較倆個函式是否相等的函式,就要分別再寫倆個,但是我們發現這些函式的功能基本一致,只是型別不同,所以我們就可以使用模板

 

模板的格式:

template<class 引數1,calss 引數2,class引數n>

返回值 函式名(引數列表)

{//……}

class也可以用typename代替,含義是相同的

下面我們來簡單的實現一個模板函式:

template<typename T>
bool IsEqual(const T& left,const T& right)
{
	return left == right;
}

void Test()
{
	string s1("s1"), s2("s2");
	cout << IsEqual(s1, s2) << endl;
	cout << IsEqual(1, 1) << endl;
}

 模板的呼叫過程:

 

用模板的時候我們最好使用引用,且加上const

 

模板引數匹配及顯示例項化 :

我們發現一個引數是int,一個引數是double,這要呼叫函式是不行的。因為在呼叫一個模板函式時,編譯器會根據引數的型別自動生成一個函式,而引數型別不一樣時,編譯器就不知道該自動生成哪種型別引數的函式。但是如果我們顯示指定的話,編譯器就會按照指定的型別去生成一個函式

函式名<型別>(引數列表);

要顯示例項化,但是如果函式的引數是同一種型別可以不顯示<int>,<double>

void Test()
{    
        cout<<IsEqual(1,1)<<endl;
	//cout << IsEqual(1, 1.2) << endl;
	cout << IsEqual<int>(1, 1.2) << endl;
	cout << IsEqual<double>(1, 1.2) << endl;
}

但是這樣呼叫的結果是不一樣的,資料會根據型別進行轉換: 

 二、模板類

1.模板類的形式:
 

template<class 形參1,class 形參2,class 形參n>
class 類名
{//…}
  • 模板類和模板函式都是以template開始,後接模板形參列表組成。模板形參不能為空,一旦宣告瞭類别範本就可以用類别範本的形參名宣告類中的成員變數和成員函式。即使類中用內建型別的地方都可以使用模板形參來宣告 
template<class T>
class AA
{

public:
        T _check(T a)
        {}
private:
        T _data;
}

該類中定義了一個型別為T的成員變數, 定義了一個返回值為T,引數為T的成員函式

最好不要在類中使用malloc,realloc,calloc,因為他們沒有呼叫建構函式,容易出錯 

2.模板類物件的建立:

  • 建立物件時,要在類名後加上<>,裡面寫清楚需要建立的型別。這樣這個物件在使用的時候,類中凡是用到模板的地方都會被替換成<>中的型別。
  • 模板類不存在實參型別的推斷。
  • 當模板類有多個模板時,建立物件要使用:類名<型別1,型別2> 物件名;中間用逗號隔開
  • 一個模板類AA,在建立其物件時要使用:AA<int> a1;  如果BB有倆個模板時,建立其物件可以用BB<int,double> b;
template<typename T>
class AA
{
private:
	T* _data;
};
 
template<typename P,typename V>
class BB
{
private:
	P _a;
	V _b;
};

void Test()
{
	AA<int> a1;
	BB<int, double> b1;
}

3.類外定義模板函式的方法:

template<模板形參列表>
函式返回值 類名<模板形參名>::函式名(引數列表)
{
 //…
}
class AA
{
public:
	void Print();
private:
	T* _data;
};

void AA<int>::Print()
{
	cout << _data << endl;
}

 模板的優點:

  1. 模板複用了程式碼,節省資源,更快的迭代開發,c++的標準模板庫(STL)因此而生
  2. 增強了程式碼的靈活性

模板的缺點:

  1. 模板讓程式碼變得凌亂複雜,不易維護,編譯程式碼時間變長
  2. 出現模板編譯錯誤時,錯誤資訊非常凌亂,不易定位錯誤

 

 

 

相關文章