相互依赖的类可能存在的问题

时间:2014-04-09 19:55:29

标签: c++ class iterator circular-dependency doubly-linked-list

我不确定我是否完全理解我遇到的问题,但就我可以解决的问题而言,这是以下几点。

我试图创建一个类来存储可以存储数据的双向链接节点列表。我也试图为这个类创建一个迭代器。

列表类和迭代器类是分开的,但显然彼此依赖,但似乎由于它们的相互依赖性,一个或另一个将无法正常运行。

我现在已将这两个类合并为一个文件,并将包含以下参考代码:

#ifndef DLINKEDLIST_H
#define DLINKEDLIST_H

#include "Header.h"
#include "DListNode.h"
#include "DListIterator.h"

    class DLinkedList
{
public:
    DListNode* m_head;
    DListNode* m_tail;
    int m_count;

    DLinkedList()
    {
        m_head = 0;
        m_tail = 0;
        m_count = 0;
    }

    ~DLinkedList()
    {
        // temporary node pointers.
        DListNode* itr = m_head;
        DListNode* next;
        while (itr != 0)
        {
            // save the pointer to the next node.
            next = itr->m_next;
            // delete the current node.
            delete itr;
            // make the next node the current node.
            itr = next;
        }
    }

    void Append(Player p_data)
    {
        if (m_head == 0)
        {
            // create a new head node.
            m_head = m_tail = new DListNode;
            m_head->m_data = p_data;
        }
        else
        {
            // insert a new node after the tail and reset the tail.
            m_tail->InsertAfter(p_data);
            m_tail = m_tail->m_next;
        }
        m_count++;
    }

    void Prepend(Player p_data)
    {
        // create the new node.
        DListNode* newnode = new DListNode;
        newnode->m_data = p_data;
        newnode->m_next = m_head;
        // set the head node and the tail node if needed.
        m_head = newnode;
        if (m_tail == 0)
            m_tail = m_head;
        m_count++;
    }

    void RemoveHead()
    {
        DListNode* node = 0;

        if (m_head != 0)
        {
            // make node point to the next node.
            node = m_head->m_next;
            // then delete the head and make the pointer point to node.

            delete m_head;
            m_head = node;

            // if the head is null, then you’ve just deleted the only node
            // in the list. set the tail to 0.
            if (m_head == 0)
                m_tail = 0;
            m_count--;
        }
    }

    void RemoveTail()
    {
        DListNode* node = m_head;
        // if the list isn’t empty, then remove a node.
        if (m_head != 0)
        {
            // if the head is equal to the tail, then
            // the list has 1 node, and you are removing it.
            if (m_head == m_tail)
            {
                // delete the node and set both pointers
                // to 0.
                delete m_head;
                m_head = m_tail = 0;
            }
            else
            {
                // skip ahead until you find the node
                // right before the tail node
                while (node->m_next != m_tail)
                    node = node->m_next;
                // make the tail point to the node before the
                // current tail and delete the old tail.
                m_tail = node;
                delete node->m_next;
                node->m_next = 0;
            }
            m_count--;
        }
    }

    DListIterator GetIterator()
    {
        return DListIterator(this, m_head);
    }
};

class DListIterator
{
public:
    DListNode* m_node;
    DLinkedList* m_list;

    DListIterator(DLinkedList* p_list = 0, DListNode* p_node = 0)
    {
        m_list = p_list;
        m_node = p_node;
    }

    void Start()
    {
        if (m_list != 0)
            m_node = m_list->m_head;
    }

    void Forth()
    {
        if (m_node != 0)
            m_node = m_node->m_next;
    }

    Player Item()
    {
        return m_node->m_data;
    }

    bool Valid()
    {
        return (m_node != 0);
    }
};

#endif

有没有解决这个问题的方法,还是我完全错误地识别了它? 导致我结论的是当我切换类的顺序(即将DListIterator类放在DLinkedList类之上)时,我得到了不同的错误/警告选择(我将在下面包含这些警告以供参考)

如果有人想查看更多代码供我参考,请告诉我。

WARNINGS/ERRORS
Error   1   error C2146: syntax error : missing ';' before identifier 'GetIterator' 
Error   2   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Error   3   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Warning 4   warning C4183: 'GetIterator': missing return type; assumed to be a member function returning 'int'
Error   5   error C3861: 'DListIterator': identifier not found  
Error   6   error C2440: 'initializing' : cannot convert from 'int' to 'DListIterator

1 个答案:

答案 0 :(得分:0)

对第二个类使用前向声明,并将成员函数从第一个类定义中移出作为必要。使用inline并保留标头中的定义可以保留预期的内联语义。