【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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted on 2015-09-23 19:26  ruan875417  阅读(212)  评论(0编辑  收藏  举报

导航