我的任务是创建一个类似于标准库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文件中定义的;他们都碰巧被删除了一小段文章。
答案 0 :(得分: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;
}
与其他一些答案不同。 Friendship does NOT break encapsulation。事实上,通过使朋友成为类接口的一部分来增加封装(当正确完成时)。然而,它确实将朋友与班级紧密联系在一起。
这正是迭代器所需要的。为了使迭代器高效工作,它需要知道类的内部,因此它通常是朋友(或内部类)。它增加了类的可用性,而不会暴露类的内部工作,代价是它将迭代器与类紧密耦合(因此,如果你更改类,则需要更改迭代器的实现(但这不是意料之外的) ))。
答案 1 :(得分:2)
到目前为止,最简单的方法是将迭代器嵌套在列表类中:
class list {
Node *head, *tail;
class iterator {
Node *node;
list *list;
// ...
};
};
如果你不想这样做,你需要将list
和list_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
..