首頁 > 軟體

C++深入瞭解模板的使用

2022-06-23 14:00:31

一.泛型程式設計

泛型程式設計:不再是針對某種型別,能適應廣泛的型別,跟具體的型別無關的程式碼

如何實現一個通用的交換函數呢?

void Swap(int& left, int& right)
{
	int temp = left;
	left = right;
	right = temp;
}
void Swap(double& left, double& right)
{
	double temp = left;
	left = right;
	right = temp;
}

使用函數過載雖然可以實現,但是有一下幾個不好的地方: 1. 過載的函數僅僅是型別不同,程式碼複用率比較低,只要有新型別出現時,就需要使用者自己增 加對應的函數 2. 程式碼的可維護性比較低,一個出錯可能所有的過載均出錯

因此我們需要告訴編譯器一個模子,讓編譯器根據不同的型別利用該模子來生成程式碼

二.函數模板

模板分為:函數模板,類別範本

1.函數模板概念

函數模板代表了一個函數家族,該函數模板與型別無關,在使用時被引數化,根據實參型別產生 函數的特定型別版本。

2.函數模板格式

template<typename T>

返回值型別 函數名(參數列){}

說明:

1.template<class T> 和 template<typename T>在此暫時認為一樣,template<struct T>是 錯誤的 ,沒有這種寫法

2.T是type的縮寫,T不一定寫T,可以寫任意字母,比如X,t ……但是習慣寫為T

舉例:

template<typename T>    //或template<class T>
void Swap(T& left, T& right)
{
	T tmp = left;
	left = right;
	right = tmp;
}
int main()
{
	int a = 0, b = 1;
	double c = 2.2, d = 3.3;
	swap(a, b);
	swap(c, d);
	return 0;
}

swap(a, b);swap(c, d); 呼叫的是同一個函數嗎?

答:不是同一個。底層組合可以看出不是同一個,如果偵錯時發現走的是同一個函數,其實是編譯器的優化導致。

實際上以後swap函數都不用自己寫了,庫中有模板,直接用就行

3.函數模板的原理

在編譯器編譯階段 ,對於模板函數的使用, 編譯器需要根據傳入的實參型別來推演生成對應型別 的函數 以供呼叫。比如: 當用 double 型別使用函數模板時,編譯器通過對實參型別的推演,將 T 確定為 double 型別,然後產生一份專門處理 double 型別的程式碼 ,對於字元型別也是如此。 模板的範例化:

三.類別範本

類別範本的定義格式

template < class T1 , class T2 , ..., class Tn >

class 類別範本名

{

// 類內成員定義

};

舉例:呼叫 Stack<int> st1; 時,用int替換模板中的T。呼叫 Stack<double> st1; 時,用double替換模板中的T

// 類別範本
template<class T>
class Stack
{
public:
	Stack(int capacity = 0)
	{
		_a = new T[capacity];
		_capacity = capacity;
		_top = 0;
	}
	~Stack()
	{
		cout << "~Stack()" << endl;
		delete[] _a;
		_capacity = 0;
		_top = 0;
	}
	void Push(const T& x)
	{}
private:
	T* _a;
	int _top;
	int _capacity;
};
int main()
{
	Stack<int> st1; // int
	st1.Push(1);
	Stack<double> st2; // double
	st2.Push(2.2);
	return 0;
}

到此這篇關於C++深入瞭解模板的使用的文章就介紹到這了,更多相關C++模板內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com