链表List的代码,但是缺少保护

来源:互联网 发布:苹果电脑mac地址 编辑:程序博客网 时间:2024/05/01 07:26
template <typename Object>        //这里的实现是不改变data的class List{private:struct Node              //struct是public的,这里把它作为private,也没毛病,就是Node里的东西List类都能用{Object data;Node *prev;Node *next;Node(const Object &d = Object(), Node *p = NULL, Node *n = NULL) :data(d), prev(p), next(n){}  //这种构造办法很好,不容易出错,建议用};public:class const_iterator{public:const_iterator() :current(NULL){}const Object & operator* () const         //*的运算符重载,取数据的,protect里有retrieve{return retrieve();}const_iterator & operator++()             //前缀的++(++i),使用空参数列表。前缀比后缀快,所以编程的时候尽量用++i......{current = current->next;return *this;}const_iterator operator++ (int)           //后缀的++(i++),给后缀指定一个匿名的int参数,int参数是不会使用的,只是一个不同的标识{const_ierator old = *this;++(*this);return old;}bool operator== (const const_iterator &rhs) const{return current == rhs.current;}bool operator!=(const const_iterator &rhs) const{return !(*this == rhs);}protected:Node *current;                         //current是指向Node的指针,不能是私有的,否则iterator将不能访问这个指针。protect允许继承的类具有访问这些成员的权限,但是不允许其他的类访问Object & retrieve() const{return current->data;}const_iterator(Node *p) :current(p){}          //不希望所有的类都能访问这个const_iterator的构造函数,但是希望iterator可以访问,所以放到了protect里friend class List < Object > ;};class iterator:public const_iterator      //两个迭代器类型,用了继承。{public:iterator(){}Object & operator*()    //*可以修改的重载{return retrieve();}const Object & operator* () const    //*只能访问的重载,不能改变,简单使用了与const_iterator完全相同的实现{return const_iterator::operator*();           //在iterator中,修改函数必须显示实现,因为不这样的话原始的实现就会被新加的修改函数隐藏}iterator & operator++ ()                   //这里operator==和operator!=不需要改变,但是++要改变,因为类型改变了,这个新的实现隐藏了const_iterator的原始实现{current = current->next;           return *this;}iterator operator++ (int){iterator old = *this;++(*this);return old;}protected:iterator(Node *p) :const_iterator(p){}friend class List < Object > ;};public:List()                                   //喜闻乐见,List的构造函数,拷贝构造函数,析构函数,=的运算符重载{init();}List(const List & rhs){init();*this = ths;}~List(){clear();delete head;delete tail;}const List & operator=(const List &rhs){if (this == &rhs)return *this;clear();for (const_iterator itr = rhs.begin(); itr != rhs.end(); ++itr)push_back(*itr);return *this;}//一些常用小函数iterator begin()                                 //迭代器的取begin和end,这里又一次说明,begin是真的begin,end是最后一个的后一个{return iterator(head->next);                //这个iterator()是迭代器iterator的构造函数,return构造函数,是因为构造函数临时构造了一个对象,然后临时返回这个对象,所以出现了这里的return}    const_iterator begin() const{return const_iterator(head->next);}iterator end(){return iterator(tail);}const_iterator end() const{return const_iterator(tail);}int size() const                              //取大小{return theSize;}bool empty() const                          //判空{return size() == 0;}void clear()                                   //清空,调用pop_front让clear不染指节点空间的回收{while (!empty())pop_front();}Object & front()                           //取首元素,这个*iterator在迭代器的类里,*是重载过的,意思就是取data{return *begin();}const Object & front() const            //每个有两种,带const的是不能修改的,不带const的是能修改的{return *begin();}Object & back()                           //取尾元素{return *--end();}const Object & back() const{return *--end();}void push_front(const Object &x){insert(end(), x);}void push_back(const Object &x){insert(end(), x);}void pop_front(){erase(begin());}void pop_back(){erase(--end());                 //这样也是避免结点空间回收的,只有几个是涉及到节点空间的}iterator insert(iterator itr, const Object &x){Node *p = itr.current;          //让*p是指向当前结点的指针     theSize++;return iterator(p->prev = p->prev->next = new Node(x, p->prev, p));/*这个拆开看,最后iterator()里的东西,就是这个new的Node,数据是x的这个。双向链表的插入节点Node *newNode = new Node(x,p->prev,p);p->prev->next=newNode;p->prev=newNode;*/}iterator erase(iterator itr)       //删除一个的{Node *p = itr.current;iterator retVal(p->next);       //erase返回指向删除结点的下一个结点的指针,这行的作用p->prev->next = p->next;p->next->prev = p->prev;delete p;theSize--;return retVal;}iterator erase(iterator start, iterator end)    //这个是都删除的{for (iterator itr = from; itr != to;)       //这个感觉给错了,from和to应该用start和enditr = erase(itr);return to;}private:int theSize;Node *head;Node *tail;void init(){theSize = 0;head = new Node;tail = new Node;head->next = tail;tail->prev = head;}};

0 0
原创粉丝点击