1

我的任务是创建一个像标准库一样的类List。我无法让迭代器正常工作,因为它必须在从末尾递减时访问链表的尾部。这是我的头文件的一部分:

typedef int T;//for now; eventually will be templated
class list;//**forward declaration, doesn't let other classes know about _tail.**
class Node
{
    //this works fine; class definition removed to make post shorter
};
class list_iterator
{
    private:
        Node* _node;
        list* _list;
    public:
        //constructor
        list_iterator& operator--(){_node=_node?(_node->_prev):(_list->_tail);return *this;}
        //some other declarations
};
class list
{
    friend class list_iterator;
    private:
        Node/*<T>*/ *_head,***_tail**;
        int _size;
    public:
        typedef list_iterator iterator;
        //some constructors and other method declarations
        iterator begin() const {iterator it(_head);return it;}
        iterator end() const {iterator it(0);return it;}
        //more method declarations
};

我试图将重要部分加粗,但它只是用星号包围它们。注意:大部分成员函数都定义在 cpp 文件中;他们都碰巧被删除了一个简短的帖子。

4

2 回答 2

4

您只需要将方法定义operator--移出类并将其放在列表之后(或在源文件中(可能是一个更好的主意。将头文件留作声明))。

注意:将声明保留在 list_iterator 中

class list_iterator
{
    /* STUFF */
    list_iterator& operator--();
 };
class list
{ 
     /*  STUFF */ 
};

// Now list_iterator::operator-- can see all the members of list.
list_iterator& list_iterator::operator--()
{
    _node=_node?(_node->_prev):(_list->_tail);
    return *this;
}

与其他一些答案所暗示的不同。友谊不会打破封装。事实上,通过使友元成为类接口的一部分来增加封装(正确完成时)。然而,它确实将朋友与班级紧密地联系在一起。

这正是您想要的迭代器。为了使迭代器有效地工作,它需要知道类的内部结构,因此它通常是一个朋友(或内部类)。它增加了类的可用性而不暴露类的内部工作,代价是它将迭代器与类紧密耦合(因此,如果您更改类,您将需要更改迭代器的实现(但这并不意外))。

于 2012-07-17T16:29:08.933 回答
2

到目前为止,最简单的方法是将迭代器嵌套在列表类中:

class list { 
    Node *head, *tail;

    class iterator {
        Node *node;
        list *list;
    // ...
    };
};

如果您不想这样做,则需要将两者的实现拆分listlist_iterator两部分:首先是仅声明成员函数的类定义,然后是成员函数的实现:

class list;

class list_iterator { 
    // ...
    Node *n;
    list *l;
};

class list {
    // ...
    friend class list_iterator;
};

inline list_iterator& list_iterator::operator--(){
    _node=_node?(_node->_prev):(_list->_tail);
    return *this;
}

这样,list在您list *定义list_iterator. 然后_tail已经在里面定义了list,那么你就有了list_iterator::operator--实际需要用到的代码list::_tail..

于 2012-07-17T16:22:56.523 回答