【c++ templates讀書筆記】【2】類模板

1、類模板的聲明

template <typename T>
class Stack{
  ...
}

2、在類模板內部,T可以像其他任何類型一樣,用於聲明成員變量和成員函數。

template <typename T>
class Stack{
private:
	std::vector<T> elemes;    // 存儲元素的容器

public:
	Stack();                  // 構造函數
	void Push(const T& e);   // 壓入元素
	void Pop();              // 彈出元素
	T Top() const;        // 返回棧頂元素
};

這個類的類型是Stack<T>,其中T是模板參數。

3、類模板具體例子

#include<iostream>
#include<vector>
#include<string>
using namespace std;

template<typename T>
class Stack{
private:
	vector<T> vec;
public:
	void push(T const& elem);
	void pop();
	T top() const;
	bool empty() const{
		return vec.empty();
	}
};
template<typename T>
void Stack<T>::push(T const& elem){
	vec.push_back(elem);
}
template<typename T>
void Stack<T>::pop(){
	if (vec.empty()){
		throw out_of_range("Stack<>::pop():empty stack");
	}
	vec.pop_back();
}
template<typename T>
T Stack<T>::top() const{
	if (vec.empty()){
		throw out_of_range("Stack<>::pop():empty stack");
	}
	return vec.back();
}

int main(){
	try{
		Stack<int> istk;
		istk.push(7);
		istk.push(8);
		istk.push(9);
		cout << istk.top() << endl;
		istk.pop();
		cout << istk.top() << endl;

		Stack<string> sstk;
		sstk.push("aaa");
		sstk.push("bbb");
		sstk.push("ccc");
		cout << sstk.top() << endl;
		sstk.pop();
		cout << sstk.top() << endl;
	}
	catch (exception const& ex){
		cerr << "Exception:" << ex.what() << endl;
		return EXIT_FAILURE;
	}

	system("pause");
	return 0;
}

對於類模板,成員函數只有被調用的時候才被實例化。如果類模板中含有靜態成員,那麼用來實例化的每種類型,都會實例化靜態成員。

4、類模板的特化

爲了特化一個類模板,要在起始處聲明一個template<>.接下來聲明用來特化模版的類型,這個類型被用作模版實參。

//類模板的特化
template<>
class Stack<string>{
private:
	deque<string> deq;
public:
	void push(string const& elem);
	void pop();
	string top() const;
	bool empty() const{
		return deq.empty();
	}
};
void Stack<string>::push(string const& elem){
	deq.push_back(elem);
}
void Stack<string>::pop(){
	if (deq.empty()){
		throw out_of_range("Stack<>::pop():empty stack");
	}
	deq.pop_back();
}
string Stack<string>::top() const{
	if (deq.empty()){
		throw out_of_range("Stack<>::pop():empty stack");
	}
	cout << "模板的特化:";
	return deq.back();
}

5、局部特化

template<typename T1, typename T2>
class MyClass{
  ...
};
// 局部特化,兩個模板參數類型相同
template<typename T>
class MyClass<T, T>{
  ...
};
// 局部特化,第2個模板參數是int
template<typename T>
class MyClass<T, int>{
  ...
};
// 局部特化,兩個模板參數都是指針類型
template<typename T1, typename T2>
class MyClass<T1*, T2*>{
  ...
};

6、缺省模板實參

可以爲類模板的參數定義缺省值,這些值被稱爲缺省模板實參,還可以引用之前的模板參數。

下面例子中的vector<T>就是缺省模板實參

#include<iostream>
#include<vector>
#include<string>
#include<deque>
using namespace std;

template<typename T,typename Container=vector<T>>
class Stack{
private:
	Container container;
public:
	void push(T const& elem);
	void pop();
	T top() const;
	bool empty() const{
		return container.empty();
	}
};
template<typename T, typename Container>
void Stack<T,Container>::push(T const& elem){
	container.push_back(elem);
}
template<typename T, typename Container>
void Stack<T, Container>::pop(){
	if (container.empty()){
		throw out_of_range("Stack<>::pop():empty stack");
	}
	container.pop_back();
}
template<typename T, typename Container>
T Stack<T, Container>::top() const{
	if (container.empty()){
		throw out_of_range("Stack<>::pop():empty stack");
	}
	return container.back();
}

int main(){
	try{
		Stack<int> istk;
		istk.push(7);
		istk.push(8);
		istk.push(9);
		cout << istk.top() << endl;
		istk.pop();
		cout << istk.top() << endl;

		Stack<string,deque<string>> sstk;
		sstk.push("aaa");
		sstk.push("bbb");
		sstk.push("ccc");
		cout << sstk.top() << endl;
		sstk.pop();
		cout << sstk.top() << endl;
	}
	catch (exception const& ex){
		cerr << "Exception:" << ex.what() << endl;
		return EXIT_FAILURE;
	}

	system("pause");
	return 0;
}

發佈了155 篇原創文章 · 獲贊 22 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章