【问题标题】:Iterator as a separate class outside of the class of a linked list in C++迭代器作为 C++ 中链表类之外的单独类
【发布时间】:2026-01-18 15:35:01
【问题描述】:

我正在尝试处理教授要求链接列表的迭代器必须是单独的头文件的任务。

但是,我见过的所有迭代器的实现都在 bag/list 类中定义了类。所以我不知道如何在包中创建一个迭代器,比如

dlist<int>::iterator it1

没有在列表中定义它。

作为参考,这里是我的列表、节点和迭代器类:

dnode.h

template <class T>
class dnode{
    public:
        dnode(){
            linknext = NULL;
            prevlink = NULL;
        }

        void set_data(T item){data_value = item;}

        void set_next(dnode<T> *link){linknext = link;}

        void set_prev(dnode<T> *link){prevlink = link;}

        T data()const{return data_value;}

        dnode *next(){return linknext;}
        dnode *prev(){return prevlink;}

    private:

        dnode *linknext;

        dnode *prevlink;

        T data_value;
};

dlist.h

#include "dnode.h"
#include "iterator.h"

template <class T>
class dlist{
    public:
        dlist(){head = tail = NULL;}

        void rear_insert(T data);

        void front_insert(T data);

        void front_remove();

        void rear_remove();

        void reverse_show();

        void show();

        iterator<T> begin(){return iterator<T>(head);}

        iterator<T> end(){return iterator<T>(tail);}

        iterator<T> r_begin(){return iterator<T>(tail);}

        iterator<T> r_end(){return iterator<T>(head);}

        void insert_after(iterator<T>& current,T item){
            dnode<T>* tmp;
            tmp = new dnode<T>;
            current.get_dnode()->next()->set_prev(tmp);
            tmp->set_data(item);
            tmp->set_next(current.get_dnode()->next());
            tmp->set_prev(current.get_dnode());
            current.get_dnode()->set_next(tmp);
        }

        void insert_before(iterator<T>& current,T item){
            dnode<T>* tmp;
            tmp = new dnode<T>;
            current.get_dnode()->prev()->set_next(tmp);
             tmp->set_data(item);
            tmp->set_next(current.get_dnode());
            tmp->set_prev(current.get_dnode()->prev());
            current.get_dnode()->set_prev(tmp);


        }
              friend class iterator<T>;
    private:
        dnode<T> *head;
        dnode<T> *tail;

};

迭代器.h

template <class T>
    class iterator
{
    public:    
        iterator(dnode<T> *first = NULL){current = first;}

    dnode<T>* get_dnode(){return current;}

    T& operator *()const{return current->data();}

    iterator& operator ++(){
        current = current->next();
        return *this;
    }

    iterator& operator ++(int){
        iterator original(current);
        current = current->next();
        return original;
    }

    iterator& operator --(){
        current = current->prev();
        return *this;
    }

    iterator& operator --(int){
        iterator original(current);
        current = current->prev();
        return original;
    }

    bool operator ==(const iterator something)const{ return current == something.current;}

    bool operator !=(const iterator something)const{ return current == something.current;}




private:
    dnode<T> *current;


};

感谢您的帮助。

【问题讨论】:

  • 你应该看看朋友的方法/类
  • 类似于在迭代器类中包含朋友类列表?
  • 关闭。为了减少耦合,让 Iterator 类成为 List 类的朋友
  • 然后在列表类中创建一个方法,该方法返回一个迭代器以对其进行迭代
  • dlist.cpp 是错字,不是吗?应该是dlist.h?如果没有,您可能会在将来某个时候在链接器上遇到一些麻烦。

标签: c++ class templates linked-list iterator


【解决方案1】:

您可以在列表类中声明迭代器和节点类型,但在别处定义它们。您需要的语法格式如下:

template <class T>
class list {
public:
    class iterator;
    struct node;

    node* head;

    iterator begin()
    {
        return head;
    }

    iterator end()
    {
        return head->prev;
    }
};

template <class T>
class list<T>::iterator {
    node* pos;
public:
    iterator(node* p) : pos (p) { }
    // ...
};

template <class T>
struct list<T>::node {
    node* next;
    node* prev;
    // ...
};

void f()
{
    list<int> l;
    list<int>::iterator i = l.begin();
    list<int>::node n;


}

当在列表、节点或迭代器的定义中时,您应该不再需要 list:: 前缀。在外部(包括在这些类之外定义的函数的返回类型),您确实需要 list:: 前缀。

在这种形式中,您的包含结构将与上面的结构相反,其中 list.h 不需要包含 node.h 或 iterator.h,但这两个文件都将包含 list.h。您可能希望在 list.h 的末尾包含 node.h 和 iterator.h,以便您的类的用户可以通过包含 list.h 来获取所有定义。

【讨论】:

  • 另一件事是它们是单独编译的头文件,所以我不能有 dlist::iterator 没有编译器因为使用它不知道存在的类而对我生气