在了解了模板与泛型的基础知识后,我们就可以着手编写自己的泛型程序了,现在,我们来实现一个自己的Queue类模板,实现标准库queue类的部分接口并自己添加一些操作。
1.思路
我们采用链表来实现Queue,我们定义了两个类:QueueItem和Queue,QueueItem用于存储Queue中元素的值,Queue中存储指向链表头和尾的两个指针。
2.QueueItem
因为QueueItem仅仅是一个为了实现Queue的辅助类,除了Queue,我们不希望别的代码使用它,所以QueueItem类是一个私有类,所有数据成员和借口呀都是私有的,为了让Queue能够使用它,我们还需要将Queue设为QueueItem的友元类。
template <typename Type> class QueueItem{
template <typename T> friend class Queue;
//数据成员
Type item;
QueueItem *next;
//构造函数
QueueItem(const Type &t): item(t), next(0) { }
};
友元声明注意:
- friend 关键字跟在template以及模板形参列表后面
- 友元声明中typename后的模板形参名不能和上面一行QueueItem定义中typename后的模板形参名系统,故此处一个用了T,一个用了Type
如果前面没有声明Queue类,我们可以像上面那样声明友元关系;若在QueueItem定义之前声明了Queue类,我们还可以这样声明友元关系:
friend class Queue<Type>;
注意Queue后面需要指定模板实参是与QueueItem定义中一样的Type。
2.基本接口
我们首先给出Queue类模板的大体框架和几个基本接口:
template <typename Type> class Queue{
public:
//默认构造函数
Queue(): head(0), tail(0), size_of_queue(0) { };
//复制控制成员
Queue(const Queue &Q): head(0), tail(0), size_of_queue(0) { copy_elems(Q); }
Queue &operator=(const Queue &);
//析构函数
~Queue();
//基本操作接口
Type &front() { return head->item; }
const Type &front() const { return head->item; }
void push(const Type &);
void pop();
bool empty() { return head == 0; }
int size() { return size_of_queue; }
private:
//数据成员:链表头尾以及链表size
QueueItem *head;
QueueItem *tail;