简体   繁体   English

如何使2个c ++类了解彼此的数据成员?

[英]How can I make 2 c++ classes know about each other's data members?

My assignment is to make a class that acts like a standard library List . 我的任务是制作一个类似于标准库List I am unable to get the iterator to work properly, because it must access the tail of the linked list when decrementing from the end. 我无法使迭代器正常工作,因为从末尾开始递减时,它必须访问链接列表的尾部。 Here is a section of my header file: 这是我的头文件的一部分:

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

I tried to bold the important parts, but it is just surrounding them with asterisks. 我试图加粗重要部分,但它只是用星号包围。 NOTE: Most of the member functions are defined in the cpp file; 注意:大多数成员函数是在cpp文件中定义的。 they all happen to be removed for a short post. 他们碰巧被删除了一个简短的职位。

You just need to move the method definition of operator-- out of the class and put it after list (or in the source file (probably a better idea. Leave the header file for declarations)). 您只需要将operator--的方法定义移出类,然后将其放在列表之后(或放在源文件中(可能是一个更好的主意。请保留头文件进行声明))。

Note: Leave the declaration inside list_iterator 注意:将声明保留在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;
}

Unlike what some other answers suggest. 与其他答案不同。 Friendship does NOT break encapsulation . 友谊不会破坏封装 In fact in increases encapsulation (when done correctly) by making the friend part of the classes interface. 实际上,通过使好朋友成为类接口的一部分来增加封装(正确完成时)。 It does however tightly bind the friend to the class. 但是,它确实将朋友与班级紧密联系在一起。

This is exactly what you want for iterators. 这正是您想要的迭代器。 For the iterator to work efficiently it needs to know the internals of the class so it is usually a friend (or an internal class). 为了使迭代器有效地工作,它需要了解类的内部,因此通常是朋友(或内部类)。 It increases the usability of the class without exposing the internal workings of the class at the cost that it tightly couples the iterator to the class (so if you change the class you will need to change the implementation of the iterator (but this is not unexpected)). 它增加了类的可用性,而又不暴露类的内部工作,而又以将迭代器与类紧密耦合为代价(因此,如果您更改类,则需要更改迭代器的实现(但这并不意外) ))。

By far the easiest way is to nest the iterator inside the list class: 到目前为止,最简单的方法是将迭代器嵌套在列表类中:

class list { 
    Node *head, *tail;

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

If you don't want to do that, you'll need to split the implementations of both list and list_iterator into two pieces: first a class definition that only declares the member functions, then implementations of the member functions: 如果您不想这样做,则需要将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;
}

This way, list has been declared by the time you define the list * in the definition of list_iterator . 这样, list已经由您定义的时间申报list *中的定义list_iterator Then _tail has been defined in list , then you have the code in list_iterator::operator-- that actually needs to use list::_tail .. 然后在list定义了_tail ,然后在list_iterator::operator--中有代码,实际上需要使用list::_tail

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM