六、完整的Queue类
Queue的完整定义:
template <typename Type> class Queue; template <typename Type> ostream &operator<<(ostream &,const Queue<Type> &); template <typename Type> class QueueItem { friend class Queue<Type>; friend ostream & operator<< <Type>(ostream &,const Queue<Type> &); QueueItem(const Type &t):item(t),next(0) {} Type item; QueueItem *next; }; template <typename Type> class Queue { friend ostream & operator<< <Type>(ostream &,const Queue<Type> &); public: Queue():head(0),tail(0) {} template <typename Iter> Queue(Iter beg,Iter end):head(0),tail(0) { copy_elems(beg,end); } Queue(const Queue &Q):head(0),tail(0) { copy_elems(Q); } Queue &operator=(const Queue &); ~Queue() { destroy(); } template <typename Iter> void assign(Iter,Iter); Type &front() { return head -> item; } const Type &front() const { return head -> item; } void push(const Type &); void pop(); bool empty() const { return head == 0; } private: QueueItem<Type> *head; QueueItem<Type> *tail; void destroy(); void copy_elems(const Queue &); template <typename Iter> void copy_elems(Iter,Iter); }; #include “Queue.cpp”
//P559 习题16.43 + P551习题16.34 template <typename Type> class List; template <typename Type> class ListItem { friend class List<Type>; ListItem(Type &t):item(t),next(0) {} Type item; ListItem *next; }; template <typename Type> class List { public: List():front(0),end(0) {} List(const List &rhs):front(0),end(0) { copy_elems(rhs); } template <class Iter> List(Iter first,Iter last):front(first),end(last) { copy_elems(first,last); } List &operator=(const List &rhs); ~List() { destroy(); } void insert(ListItem<Type> *ptr,Type &value); void del(ListItem<Type> *ptr); ListItem<Type> *find(const Type &value); ListItem<Type> *first() const { return front; } ListItem<Type> *last() const { return end; } bool empty() const { return front == 0; } Type &getElem(ListItem<Type> *ptr) { return ptr -> item; } template <class Iter> void assign(Iter,Iter); private: ListItem<Type> *front,*end; void destroy(); void copy_elems(List &); template <class Iter> void copy_elems(Iter,Iter); }; template <typename Type> void List<Type>::destroy() { while (!empty()) del(front); } template <typename Type> void List<Type>::del(ListItem<Type> *ptr) { ListItem<Type> *p = front; while (p != 0 && p != ptr && p -> next != ptr) { p = p -> next; } if (p != 0) { if (p == ptr) { front = ptr -> next; } else { p -> next = ptr -> next; } if (ptr == end) { end = ptr -> next; } delete ptr; } else { throw out_of_range("no such element"); } } template <typename Type> void List<Type>::insert(ListItem<Type> *ptr,Type &val) { ListItem<Type> *pt = new ListItem<Type>(val); if (empty()) { front = pt; } else { pt -> next = ptr -> next; ptr -> next = pt; } if (ptr == end) { end = pt; } } template <typename Type> void List<Type>::copy_elems(List<Type> &rhs) { for (ListItem<Type> *pt = rhs.front; pt ; pt = pt -> next) { insert(end,pt -> item); } } template <class Type> template <typename Iter> void List<Type>::copy_elems(Iter first,Iter last) { while (first != last) { insert(end,first -> item); first = first -> next; } insert(end,first -> item); } template <typename Type> List<Type> &List<Type>::operator=(const List<Type> &rhs) { destroy(); copy_elems(rhs); } template <typename Type> ListItem<Type> *List<Type>::find(const Type &value) { ListItem<Type> *pt = front; while (pt && pt -> item != value) { pt = pt -> next; } return pt; } template <class Type> template <typename Iter> void List<Type>::assign(Iter first,Iter last) { destroy(); copy_elems(first,last); }
//习题16.44 template <class Type> class Queue; template <typename Type> ostream &operator<<(ostream &os,const Queue<Type> &); template <class Type> class Queue { friend ostream &operator<< <Type>(ostream &os,const Queue<Type> &); public: Queue() {} template <typename Iter> Queue(Iter beg,Iter end):items(beg,end) {} template <typename Iter> void assign(Iter beg,Iter end) { items.assign(beg,end); } Type &front() { return items.front(); } const Type &front() const { return items.front(); } void push(const Type &t) { items.push_back(t); } void pop() { items.erase(items.begin()); } bool empty() const { return items.empty(); } private: list<Type> items; };
七、类模板的static成员
类模板可以像任意其他类一样声明static成员。
template <class T> class Foo { public: static std::size_t count() { return ctr; } private: static std::size_t ctr; };
定义了名为Foo的类模板,它有一个名为count的publicstatic成员函数和一个名为ctr的privatestatic 数据成员。
Foo类的每个实例化[谨记:不是每个对象]都有自己的static成员:
Foo<int> fi,fi2,fi3; Foo<string> fs;
每个实例化表示截然不同的类型,所以给定实例化所有对象都共享一个static成员。因此,Foo<int>类型的任意对象共享同一static成员 ctr,Foo<string> 类型的对象共享另一个不同的ctr成员。
1、使用类模板的static成员
通常,可以通过类类型的对象访问static成员或者使用作用域操作符直接访问static成员。当然,当试图通过类使用static成员的时候,必须引用实际的实例化:
Foo<int> fi,fi2; size_t ct = Foo<int>::count(); ct = fi.count(); ct = fi2.count(); ct = Foo::count(); //Error:不知道运用哪个实例化
注:static成员函数只有在程序中使用时才进行实例化。
2、定义static成员
像使用任意其他static数据成员一样,必须在类外部出现数据成员的定义。在类模板含有static成员的情况下,成员定义必须指出它是类模板的成员:
template <typename Type> std::size_t Foo<Type>::ctr = 0;
static数据成员的名字以Foo<T>::为前缀,表示成员属于类模板Foo。