C++模板中的嵌套
在下面的程序中,我们创建了一个模板类用于实现Queue容器的部分功能,并且在模板类中潜逃使用了一个Node类。
queuetp.h
// queuetp.h -- queue template with a nested class #ifndef QUEUETP_H_ #define QUEUETP_H_ template <class Item> class QueueTP { private: enum {Q_SIZE = 10}; // Node is a nested class definition class Node { public: Item item; Node * next; Node(const Item & i) : item(i), next(0) {} }; Node * front; // pointer to front of Queue Node * rear; // pointer to rear of Queue int items; // current number of items in Queue const int qsize; // maximum number of items in Queue QueueTP(const QueueTP & q) : qsize(0) {} QueueTP & operator=(const QueueTP & q) { return *this; } public: QueueTP(int qs = Q_SIZE); ~QueueTP(); bool isempty() const { return items == 0; } bool isfull() const { return items == qsize; } int queuecount() const { return items; } bool enqueue(const Item &item); // add item to end bool dequeue(Item &item); // remove item from front }; // QueueTP methods template <class Item> QueueTP<Item>::QueueTP(int qs) : qsize(qs) { front = rear = 0; items = 0; } template <class Item> QueueTP<Item>::~QueueTP() { Node * temp; while (front != 0) // while queue is not yet empty { temp = front; front = front->next; delete temp; } } // Add item to queue template <class Item> bool QueueTP<Item>::enqueue(const Item & item) { if (isfull()) return false; Node * add = new Node(item); // create node // on failure, new throws std::bad_alloc exception items ++; if (front == 0) // if queue is empty front = add; // place item at front else rear->next = add; // else place at rear rear = add; return true; } // Place front item into item variable and remove from queue template <class Item> bool QueueTP<Item>::dequeue(Item & item) { if (front == 0) return false; item = front->item; // set item to first item in queue items --; Node * temp = front; // save location of first item front = front->next; // reset front to next item delete temp; // delete former first item if (items == 0) rear = 0; return true; } #endif // QUEUETP_H_
这里,Node是利用通用类型Item类定义的。所以,下面的声明将导致Node被定义成用于存储double值:
QueueTp<double> dq;
而下面的声明将导致Node被定义沉用于存储char值:
QueueTp<char> cq;
这两个Node类将在两个独立的QueueTP类中定义,因此不会发生名称冲突。即一个节点的类型为QueueTP<double>::Node,另一个节点的类型为QueueTP<char>::Node。
下面的程序用于测试这个新的类。
nested.cpp
//nested.cpp -- using a queue that has a nested class #include <iostream> #include <string> #include "queuetp.h" int main() { using std::string; using std::cin; using std::cout; QueueTP<string> cs(5); string temp; while (!cs.isfull()) { cout << "Please enter your name. You will be " << "served in the order of arrival.\n" << "name: "; getline(cin, temp); cs.enqueue(temp); } cout << "The queue is full. Processing begins!\n"; while (!cs.isempty()) { cs.dequeue(temp); cout << "Now processing " << temp << "...\n"; } return 0; }
效果:
Please enter your name. You will be served in the order of arrival. name: moonlit Please enter your name. You will be served in the order of arrival. name: moon Please enter your name. You will be served in the order of arrival. name: light Please enter your name. You will be served in the order of arrival. name: moonlight poet Please enter your name. You will be served in the order of arrival. name: paul jackson The queue is full. Processing begins! Now processing moonlit... Now processing moon... Now processing light... Now processing moonlight poet... Now processing paul jackson...