2012-03-15 82 views
0

我有一個類列表:無限循環打印列表

#ifndef UTIL_H 
#define UTIL_H 

#include <iostream> 
#include <exception> 

namespace Util 
{ 

class IndexOutOfBounds : public std::exception 
{ 
    virtual const char* what() 
    { 
     return "Index out of bounds"; 
    } 
}; 

template<class T> 
class Iterator; 

template <class T> 
class ListNode 
{ 

    template<class R> 
    friend class Iterator; 
    template<class R> 
    friend class List; 

    public: 

    ListNode() 
    { 
     init(); 
    } 
    ListNode(T info) 
    { 
     init(); 
     this->info=info; 
    } 
    static void link(ListNode<T> first, ListNode<T> second) 
    { 
     first.next=&second; 
     second.prev=&first; 
    } 
    template<class R> 
    friend std::ostream& operator<< (std::ostream& out, const ListNode<R>& node); 
    template<class R> 
    friend std::istream& operator>> (std::istream& in, const ListNode<R>& node); 

    private: 

    T info; 
    ListNode<T>* next; 
    ListNode<T>* prev; 
    void init() 
    { 
     next=prev=this; 
    } 
}; 

template<class T> 
std::ostream& operator<< (std::ostream& out , const ListNode<T>& node) 
{ 
    out << node.info; 
    return out; 
} 

template<class T> 
std::istream& operator>> (std::istream& in , const ListNode<T>& node) 
{ 
    in >> node.info; 
    return in; 
} 

template <class T> 
class List 
{ 
    friend class ListNode<T>; 
    template <class R> 
    friend class Iterator; 
    private: 

    unsigned int length; 
    ListNode<T>* node; 

    public: 

    List() 
    { 
     node=new ListNode<T>(); 
     length=0; 
    } 
    unsigned int size() const 
    { 
     return length; 
    } 
    void insert(int i,T info) throw() 
    { 
     ListNode<T>* ptr=node,*next_ptr; 
     try 
     { 
      if(i>(int)length || i<0) 
       throw IndexOutOfBounds(); 
      for(int j=0;j<i;j++) 
       ptr=ptr->next; 
      next_ptr=ptr->next; 
      ptr->next=new ListNode<T>(info); 
      ptr->next->prev=ptr; 
      ListNode<T>::link(*(ptr->next),*next_ptr); 
      length++; 
     } 
     catch(IndexOutOfBounds& e) 
     { 
      throw e; 
     } 
    } 
    void push_back(T info) throw() 
    { 
     try 
     { 
      insert(length,info); 
     } 
     catch(IndexOutOfBounds& e) 
     { 
      throw e; 
     } 
    } 
    void push_front(T info) throw() 
    { 
     try 
     { 
      insert(0,info); 
     } 
     catch(IndexOutOfBounds& e) 
     { 
      throw e; 
     } 
    } 
    void remove(int i) throw() 
    { 
     ListNode<T>* ptr=node,*next_ptr; 
     try 
     { 
      if(i>=length || i<0) 
       throw IndexOutOfBounds(); 
      for(int j=0;j<i;j++) 
       ptr=ptr->next; 
      next_ptr=ptr->next->next; 
      delete ptr->next; 
      ListNode<T>::link(*ptr,*next_ptr); 
      length--; 
     } 
     catch(IndexOutOfBounds& e) 
     { 
      throw e; 
     } 
    } 
    void pop_back() throw() 
    { 
     try 
     { 
      remove(length-1); 
     } 
     catch(IndexOutOfBounds& e) 
     { 
      throw e; 
     } 
    } 
    void pop_front() throw() 
    { 
     try 
     { 
      remove(0); 
     } 
     catch(IndexOutOfBounds& e) 
     { 
      throw e; 
     } 
    } 
    Iterator<T> begin() const 
    { 
     Iterator<T> result; 
     result.ptr=node->next; 
     return result; 
    } 
    Iterator<T> last() const 
    { 
     Iterator<T> result; 
     result.ptr=node->prev; 
     return result; 
    } 
    Iterator<T> end() const 
    { 
     Iterator<T> result; 
     result.ptr=node; 
     return result; 
    } 
    template <class R> 
    friend std::ostream& operator<< (std::ostream& out , const List<R>& l) ; 
    template <class R> 
    friend std::istream& operator>> (std::istream& in , const List<R>& l); 
    typedef Iterator<T> iterator; 

}; 

template<class T> 
std::ostream& operator<< (std::ostream& out ,const List<T>& l) 
{ 
    int k=0; 
    for(Iterator<T> i=l.begin();i!=l.end();++i) 
     out << *i << "\t"; 
    return out; 
} 

template<class T> 
std::istream& operator>> (std::istream& in , const List<T>& l) 
{ 
    for(Iterator<T> i=l.begin();i!=l.end();i++) 
     in >> *i; 
    return in; 
} 

template <class T> 
class Iterator 
{ 
    friend class List<T>; 
    friend class ListNode<T>; 
    private: 

    ListNode<T>* ptr; 

    public: 

    Iterator() 
    { 
     ptr=NULL; 
    } 
    Iterator(const Iterator<T>& i) 
    { 
     ptr=i.ptr; 
    } 
    Iterator<T>& operator= (Iterator<T> i) 
    { 
     ptr=i.ptr; 
     return *this; 
    } 
    Iterator<T>& operator++() 
    { 
     ptr=ptr->next; 
     return *this; 
    } 
    Iterator<T> operator++ (int) 
    { 
     Iterator<T> i=*this; 
     ++*this; 
     return i; 
    } 
    Iterator<T>& operator--() 
    { 
     ptr=ptr->prev; 
     return *this; 
    } 
    Iterator<T> operator-- (int) 
    { 
     Iterator<T> i=*this; 
     --*this; 
     return i; 
    } 
    T& operator*() 
    { 
     return ptr->info; 
    } 
    template<class R> 
    friend bool operator!= (const Iterator<R>& i, const Iterator<R>& j); 
    template<class R> 
    friend bool operator== (const Iterator<R>& i, const Iterator<R>& j); 

}; 

template <class T> 
bool operator!= (const Iterator<T>& i, const Iterator<T>& j) 
{ 
    return i.ptr!=j.ptr; 
} 

template <class T> 
bool operator== (const Iterator<T>& i, const Iterator<T>& j) 
{ 
    return i.ptr==j.ptr; 
} 

} 

#endif 

如果主我嘗試打印:

int main(int argc, char** argv) 
{ 
List<int> l; 
for(int i=0;i<10;i++) 
    l.push_back(i); 
std::cout << l; 
return 0; 
} 

我得到了滿屏幕的數字流,我要從終端殺死進程。 所以它進入了一個無限循環,我不明白爲什麼。 也許迭代算子!=有一些問題,我不明白。

+0

你不是終止'cout'流。 「std :: endl」在哪裏? – 2012-03-15 23:08:17

+0

你嘗試過使用調試器嗎? – 2012-03-15 23:08:21

+3

'下一=分組=這一點;'..這不是一個好主意:) – 2012-03-15 23:09:32

回答

2

你不終止您的鏈接列表,在最後一個節點next指針指向回元素本身。

要麼在ListNode構造(優選的)插入新元素添加到列表時解決這個問題,或。

+0

構造函數是沒有問題的,我初始化下一=分組=這一點,但在insert方法,我鏈接與他人創建的節點。 – 2012-03-16 13:56:21