读C++ Primer 之队列类模板

来源:互联网 发布:淘宝开店保证金怎么退 编辑:程序博客网 时间:2024/06/01 11:25

在C语言学习阶段,我们学过了队列的C语言的实现,但是在C++里面,我们使用泛型实现了实现了队列类的模板,虽然有现成的队列类的模板,但是这对于我们了解怎样用泛型以及泛型编程中的一些需要注意的地方却是受益匪浅,特别是容易忘记的地方。

好了,接下来咱们上代码

首先是 templateclass.h 文件的实现

/** author:xizero00* mail:xizero00@163.com* date:2011-08-08 01:34:33 * Template Queue Sample  模板队列示例*/#ifndef TEMPLATECLASS_H#define TEMPLATECLASS_H#include <iostream>using namespace std;//Queue的实现类//这里是特定的模板友元关系,即类可以只授权特定的实例的访问权,即类Queue和类QueueItem是一对一的关系template<class T> class Queue;template <class T>class QueueItem{//因为Queue是需要使用到这个不公开接口的类中的成员,所以需要将Queue声明为友元类friend class Queue<T>;private://复制构造函数QueueItem<T>( const T &q ): item( q ) , next( 0 )  {}//元素值T item;//指向下一个元素的指针QueueItem<T> *next;};//类模板template <class T>class Queue{public://需要注意的一点是,一般在类中实现的函数都会是内联函数//使用内联函数的要求是,该函数的代码一般只有几行,并且经常执行//默认构造函数//这样的声明也是可以的//Queue() :head( 0 ) , tail( 0 ) {}Queue<T>() :head( 0 ) , tail( 0 ) {}//复制构造函数//当然这样的声明也是可以的//Queue( const Queue &q ): head( q.head ) , tail( q.tail ) { copy_elems( q ); }Queue<T>( const Queue<T> &q) :head( q.head ) , tail( q.tail ) { copy_elem( q ); }//操作符重载Queue<T>& operator= ( const Queue<T>& );//析构函数~Queue(){ destroy(); }//获取头节点的元素T& front() { return head->item; }//下面这个是const版本的//const T& front() { return head->item; }//入队列void push( const T& );//出队列void pop();//判断是否为空bool empty() const { return NULL == head; }//显示队列元素void ShowElements() ;private://队列的头指针,尾指针,主要用于出入队列用QueueItem<T> *head;QueueItem<T> *tail;//销毁队列数据void destroy();//复制元素void copy_elems( const Queue& );};//出队列,即删除队列头部的元素template<typename T> void Queue<T>::pop(){//判断是否为空指针if( NULL == head ){return;}//保存当前指针的值QueueItem<T> *p = head;//将头指针指向下一个元素head = head->next;//删除delete p;}//入队列,即从队列的尾部插入数据template<typename T>void Queue<T>::push( const T &t ){//构造一个对象QueueItem<T> *p = new QueueItem<T>( t );//在插入队列尾部的时候需要判断队列是否为空的!if( empty() ){head = tail = p;}else{//将尾指针的指向下一个元素的指针指向生成的数据tail->next = p;//将尾指针移动到最后一个数据上去tail = p;}}//销毁数据template<typename T>void Queue<T>::destroy(){//不断地出队列即可while( !empty() ){pop();}}//赋值操作符重载template<typename T>Queue<T>& Queue<T>::operator= (const Queue<T> &q){//复制队列元素,结束条件是head为空的时候for( QueueItem<T> *p= q.head ; p  ; p = p->next ){push( p->item );}}template<typename T>void Queue<T>::ShowElements(){cout << "当前队列元素为:" << endl;if( !head ){cout << "oops,当前队列为空...." << endl;}for( QueueItem<T> *p = head ; p  ; p = p->next ){cout << p->item  << endl;}}#endif //TEMPLATECLASS_H


在看完模板类的声明以及定义之后,我想提醒一下:养成良好的习惯,不要省略指定模板参数即<T>,即便是在类的声明中也不要省略<T>,这样会让你不会忘记模板参数。

否则当你在类的外面实现的时候会忘记写模板参数。

好了接下来看 templatesample.cc文件

/** author:xizero00* mail:xizero00@163.com* date:2011-08-08 01:34:33 * Template Queue Sample  模板队列示例*/#include "templateclass.h"int main( int argc , char **argv ){Queue<int> q;int data[] = { 1, 2, 4 ,5 };//入队列for( int i = 0 ; i < 4 ; i++ ){q.push( data[i] );}cout << "q队列元素如下:" << endl;q.ShowElements();Queue<int> p;//复制队列元素p = q;cout << "p队列元素如下(它是复制的q队列的元素):" << endl;p.ShowElements();cout << "对p队列进行出队列操作" << endl;p.pop();p.ShowElements();cout << "出队列操作进行3次" << endl;p.pop();p.pop();p.pop();p.ShowElements();return 0;}

下面给出编译所需的Makefile

# author:xizero00# mail:xizero00@163.com# date:2011-08-08 01:37:39 # Makefile for Template Queue Sample  模板队列示例compile:g++ templatesample.cc -g -o template./templateclean:rm -f templatels -al template*



下面给出我的运行结果:

q队列元素如下:当前队列元素为:1245p队列元素如下(它是复制的q队列的元素):当前队列元素为:1245对p队列进行出队列操作当前队列元素为:245出队列操作进行3次当前队列元素为:oops,当前队列为空....


总结:在学习模板类的时候,我想最重要的还是需要动手,其次是养成良好的编码习惯,能够让你的注释清晰易懂,让你的理解也能够让别人理解,代码看起来清清爽爽的才是最终目的,学习的目的就是和他们分享,一起进步!

原创粉丝点击