c++ - 无限循环打印列表

标签 c++

我有一个类列表:

#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;
}

我的屏幕上满是数字,我必须从终端终止进程。 所以它进入了无限循环,我不明白为什么。 也许 Iterator operator != 有一些问题,我不明白。

最佳答案

您不会终止链表,在最后一个节点中,next 指针指向元素本身。

要么在 ListNode 构造函数(首选)中修复此问题,要么在向列表插入新元素时修复此问题。

关于c++ - 无限循环打印列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9729520/

相关文章:

c++ - 为什么具有相同名称但不同签名的多重继承函数不被视为重载函数?

c# - 将 C++ COM 类转换为 C# 以供 C++ 可执行文件调用

c++ - 类的友元函数

C++ 严格弱排序派生类

c++ - 仅在当前目录中搜索标签

c++ - Arduino 上的结构 : function() 'does not name a type'

c++ - std::string::max_size() 作为静态成员

c++ - 将成员函数作为参数传递给优化器(将成员函数传递给函数)

c++ - 我应该明确地零初始化 auto_ptr 吗?

c++ - 调用 FindConnectionPoint 时访问冲突写入内存