List的實現

重要技術點:iterator可用於可用於任何需要使用const_iterator的例程裏,反之則不是。
可以在表的末尾或前端添加一個額外的結點,這些額外的結點被稱爲哨兵結點,在頭部的結點稱爲表頭結點,在末端的結點稱爲尾結點。

版本1,未檢測錯誤。

template <typename Object>
class List
{
  private:
    struct Node  //struct的成員默認爲公有
    {
        Object data;
        Node *prev;  //指向Node之前的指針
        Node *next;  //指向Node之後的指針

        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
          {return retrieve();}

        const_iterator& operator++()
        {
            current = current->next;
            return *this;
        }  //給前綴形式指定空參數表以標識

        const_iterator operator++(int)
        {
            const_iterator old = *this;
            ++(*this);
            return old;
        }  //給後綴形式指定一個(匿名的)int參數以標識,int參數永遠不使用。

         bool operator==(const const_iterator& rhs) const
           {return current == rhs.current;}
         bool operator!=(const const_iterator& rhs) const
           {return !(*this==rhs)}

       protected:
         Node *current;

         Object& retrieve() const
           {return current->data;}

         const_iterator(Node *p):current(p)  //const_iterator的構造函數
           {}

         friend class List<Object>;  //友元聲明,允許List類訪問const_iterator的非公有成員
    };

    class iterator:public const_iterator
    {
      publiciterator()
          {}

        Object& operator*()
          {return retrieve();}
        const Object& operator*() const
          {return const_iterator::operator*();}//在iterator中修改函數必須顯式實現,否則原始的實現會被新加的修改函數隱藏。

        iterator& operator++()
        {
          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()
      {init();}  //零參數構造函數

    List(const List& rhs)  //複製構造函數,這兩個函數都要分配表頭結點和尾結點,從而給出私有的init例程,init()生成一個空List。
      {
          init();
          *this = rhs;
      }

    ~List()  //回收表頭結點和尾結點,調用clear()時回收所有的其他結點。
      {
          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()
      {return iterator(head->next);}
    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()
    {
      while(!empty())
         pop_front();
    }

    Object& front()
      {return *begin();}//前面在迭代器的類定義中已經重載了*操作符,這裏不能慣性地以爲解引用之後還是指針。
    const Object& front() const
      {return *begin();}
    Object& back()
      {return *--end();}
    const Object& back() const
      {return *--end();}
    void push_front(const Object& x)
      {insert(begin(), 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)  //在itr之前插入x
    {
        Node *p = itr.current;
        theSize++;
        return iterator(p->prev = p->prev->next = new Node(x, p->prev, p));
    }

    //刪除itr所指的結點
    iterator erase(iterator itr)
    {
        Node *p = itr.current;
        iterator retVal(p->next);
        p->prev->next = p->next;
        p->next->prev = p->prev;
        delete p;
        theSize--;

        return retVal;
    }
    iterator erase(iterator start, iterator end)
    {
        for(iterator itr = start; itr != end;)
            itr = erase(itr);

        return end;
    }

  private:
    int theSize;
    Node *head;
    Node *tail;

    void init()
    {
        theSize = 0;
        head = new Node;
        tail = new Node;
        head->next = tail;
        tail->prev = head;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章