C Templates学习笔记二:类模板

一:类模板的实现

实例: 

#include <vector>
#include <stdexcept>

template <typename T> //类模板声明部分 同样可以使用class T为模板参数
class Stack {
private:
	std::vector<T> elems;

public:
	//Stack(); //构造函数
	//Stack (Stack<T> const&);  //拷贝构造函数
	//Stack<T>& operator= (Stack<T> const&);  //赋值运算符
	void push(T const&);
	void pop();
	T top() const;
	bool empty() const {
		return elems.empty();
	}
};

template <typename T>
void Stack<T>::push(T const& elem)
{
	elems.push_back(elem);
}

template<typename T>
void Stack<T>::pop()
{
	if (elems.empty())
	{
		throw std::out_of_range("Pop() empty stack");
	}
	elems.pop_back();
}

template <typename T>
T Stack<T>::top() const {
	if (elems.empty())
	{
		throw std::out_of_range("top() empty stack");
	}
	return elems.back();
}

注:类的类型是Stack<T> ,类名是stack 指定类型,构造函数 析构函数 应该用Stack

二:类模板的使用

实例:

int main()
{
	try
	{
		Stack<int>     intStack;
		Stack<std::string> stringStack;

		//使用int栈
		intStack.push(7);
		std::cout << intStack.top() << std::endl;

		//使用string栈
		stringStack.push("hello");
		std::cout << stringStack.top() << std::endl;
		stringStack.pop();
		stringStack.pop();
	}
	catch (std::exception const& ex)
	{
		//...
	}
}

注:只有在调用成员函数时才会产生实例化代码,可以节约空间和时间,而且对于使用了某些类型不支持操作的函数,不调用就可以。模板实参可以是任何类型,但是该类型必须提供被调用的所有操作。

特:stack<stack<int> > intStackStack; 两个>>中间必须要有空格 否则会被理解为operator>>

三:类模板的特化

目的:优化某种特定类型的实现,或者克服某种特定类型的不足,例如不支持某些操作等等。

特化一整个类模板,需要特化所有的成员函数

实例:

template<>
class Stack<std::string>
{
private:
	std::deque<std::string> elems;

public:
	void push(std::string const&);
	void pop();
	std::string top() const;
	bool empty() const {
		return elems.empty();
	}
};

void Stack<std::string>::push(std::string const& elem)
{
	elems.push_back(elem);
}

void Stack<std::string>::pop()
{
	if (elems.empty())
	{
		throw std::out_of_range("stack<std::string>::pop(): empty stack");
	}
	elems.pop_back();
}

std::string Stack < std::string >::top() const {
	if (elems.empty())
	{
		throw std::out_of_range("stack<std::string>::top(): empty stack");
	}
	return elems.back();
}

四:类模板的局部特化

template <typename T1, typename T2>
class MyClass {

};

//局部特化版本
template <typename T>
class MyClass<T, T> {

};

template <typename T>
class MyClass<T, int> {

};

template<typename T1, typename T2>
class MyClass<T1*, T2*> {

};

注意二义性问题。

五:缺省模板实参

template <typename T, typename CONT = std::vector<T> >
class Stack {
private:
	CONT elems;

public:
	void push(T const&);
	void pop();
	T top() const;
	bool empty() const {
		return elems.empty();
	}
};

template <typename T, typename CONT>
void Stack<T, CONT>::push(T const& elem)
{
	elems.push_back(elem);
}

template <typename T, typename CONT>
void Stack<T, CONT>::pop()
{
	if (elems.empty())
	{
		throw std::out_of_range("Stack<>::pop(): empty stack");
	}
	elems.pop_back();
}

template <typename T, typename CONT>
void Stack<T, CONT>::top() const {
	if (elems.empty()) {
		throw std::out_of_range("Stack<>::top() : empty stack");
	}
	return elems.back();
}
发布了35 篇原创文章 · 获赞 5 · 访问量 425

猜你喜欢

转载自blog.csdn.net/qq_33776188/article/details/102931056
今日推荐