類模板(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;
}
作者:csdn博客 Spike_King