您的位置:首页 > 编程语言 > C语言/C++

C++ - 类模板(class template) 详解 及 代码

2013-11-23 21:20 513 查看

类模板(class template) 详解 及 代码

本文地址: /article/1384289.html

类模板(class template)需要添加模板参数(template parameter), 即最前面添加"template <template T>";
把所有需要使用模板类型的位置, 使用"T"代替; 使用时需要填加"Class<T>",指定模板参数;
在定义类的成员函数(member function)时, 也需要添加类的模板参数"template <template T>",
并且在声明函数的归属类时, 类需要转换为模板类, 即"Class::"转换为"Class<T>::";
如果在类中, 如果使用本类对象, 即当前对象, 则可以不添加模板参数(添加也不没有问题);
其余注意初始化列表"initializer_list"的用法, 和前缀++或--与后缀++或--在重载时的区别;
代码如下:
/*   * cppprimer.cpp   *   *  Created on: 2013.11.21   *      Author: Caroline   */    /*eclipse cdt, gcc 4.8.1*/    #include <iostream>  #include <vector>  #include <initializer_list>  #include <memory>  #include <cstddef>    template <typename T> class BlobPtr;  template <typename T> class Blob;    /*Blob: Binary Large OBject*/  template <typename T> class Blob {  	friend class BlobPtr<T>;  public:  	typedef T value_type;  	typedef typename std::vector<T>::size_type size_type;  	Blob ();  	Blob (std::initializer_list<T> il); //可以使用初始化列表, {}  	size_type size() const { return data->size(); }  	bool empty() const { return data->empty(); }  	void push_back (const T &t) { data->push_back(t); }  	void push_back (T &&t) { data->push_back(std::move(t)); } //右值操作  	void pop_back ();  	T& back ();  	T& operator[] (size_type i) ;  private:  	std::shared_ptr<std::vector<T> > data;  	void check (size_type i, const std::string &msg) const; //验证给定的索引  };    template <typename T>  Blob<T>::Blob () : data(std::make_shared<std::vector<T>>()) {}    template <typename T>  Blob<T>::Blob (std::initializer_list<T> il) :          data(std::make_shared< std::vector<T> >(il)) {}    /*验证给定的索引*/  template <typename T>  void Blob<T>::check (size_type i, const std::string &msg) const  {  	if (i >= data->size())  		throw std::out_of_range (msg); //抛出异常  }    template <typename T>  T& Blob<T>::back ()  {  	check (0, "back on empty Blob");  	return data->back ();  }    template <typename T>  T& Blob<T>::operator[] (size_type i)  {  	check (i, "subscript out of range");  	return (*data)[i];  }    template <typename T>  void Blob<T>::pop_back ()  {  	check (0, "pop_back on empty Blob");  	data->pob_back ();  }    template <typename T>  class BlobPtr {  public:  	BlobPtr () : curr (0) {}  	BlobPtr (Blob<T> &a, size_t sz=0) : wptr(a.data), curr (sz) {}  	T& operator* () const {  		auto p = check (curr, "dereference past end");  		return (*p) [curr];  	}  	BlobPtr& operator++ (); //前缀操作符  	BlobPtr& operator-- ();  	BlobPtr operator++ (int); //后缀操作符  	BlobPtr operator-- (int);  private:  	std::shared_ptr<std::vector<T>> check (std::size_t, const std::string&) const;  	std::weak_ptr<std::vector<T>> wptr;  	std::size_t curr;  };    template <typename T>  std::shared_ptr<std::vector<T>>  BlobPtr<T>::check (std::size_t i, const std::string& msg) const  {  	auto ret = wptr.lock (); //判断wptr是否绑定了Blob  	if (!ret)  		throw std::runtime_error ("unbound BlobPtr");  	if (i >= ret->size ())  		throw std::out_of_range (msg);  	return ret;  }    template <typename T>  BlobPtr<T>& BlobPtr<T>::operator++ () {  	check (curr, "increment past end of BlobPtr"); //先判断后加  	++curr;  	return *this;  }    template <typename T>  BlobPtr<T>& BlobPtr<T>::operator-- () {  	--curr; //先减之后, 如果为0, 再减就是大整数  	check (curr, "decrement past begin of BlobPtr"); //先减后判断  	return *this;  }    template <typename T>  BlobPtr<T> BlobPtr<T>::operator ++(int)  {  	BlobPtr ret = *this;  	++*this; //使用重载的前缀++  	return ret;  }    template <typename T>  BlobPtr<T> BlobPtr<T>::operator --(int)  {  	BlobPtr ret = *this;  	--*this; //使用重载的前缀--  	return ret;  }    int main (void) {  	std::cout << "Hello Mystra!" << std::endl;  	Blob<int> ia;  	Blob<int> ia2 = {0, 1, 2, 3, 4};  	std::cout << "ia2[2] = " << ia2[2] << std::endl;  	BlobPtr<int> pia = ia2;  	std::cout << "*(++pia) = " << *(++pia) << std::endl;  	return 0;  }




本文出自 “永不言弃” 博客,请务必保留此出处http://spikeking.blog.51cto.com/5252771/1388001
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: