'const struct list::SingleList' 的前向声明,'list::SingleList' 不完整类型的无效使用(编译错误)

3

SingleList.h

#include "ListBase.h"
#include "DataNode.h"
#include "SingleListIterator.h"

namespace list
{
    class SingleListIterator;
    class SingleList : public ListBase
    {
        private:
            DataNode *head;
            DataNode *tail;
        public:
            SingleList();
            SingleList(const SingleList &obj);
            ~SingleList();
            void Flush(); //deletes all elements in the list
            void PushInFront(const int data); // **
            void Append(const int data); // **
            void DeleteLast();
            void DeleteFirst();
            int Delete(const int& data); // ** remove the first occurrence of data and return 1 otherwise 0
            const int& GetFirst() const; // **
            int& GetFirst(); // **
            const int& GetLast() const; // **
            int& GetLast(); // **
            void PrintList() const;
            const int IsEmpty() const;
    //        SingleList<T> &operator=(const SingleList<T>& obj) (**)
    //        const int operator==(const SingleList<T> &obj) const (**)
    //        const int operator!=(const SingleList<T> &obj) const (**)
    //        SingleList<T>& operator+(const SingleList<T> &obj) (**) // concatenates two lists
    //        operator int() // returns list size (**)
            friend class SingleListIterator; // ** ASK Changd it from Iterator
    };

SingleListIterator.h

#include "Iterator.h"
#include "SingleList.h"

namespace list
{
    class SingleList;
    class SingleListIterator: public Iterator
    {
        public:
                           // error here --> Forward declaration of 'const struct list::SingleList'
            SingleListIterator(const SingleList &list); // **
            SingleListIterator(const SingleListIterator &obj); // **
            virtual const int Current() const; // **
            virtual void Succ();
            virtual const int Terminate() const;
            virtual void rewind();
    //        T &operator++(int) (**)
    //        SingleListIterator<T>& operator=(const SingleListIterator<T>&obj) (**)
    };
            // error here --> Invalid use of incomplete type 'list::SingleList'
    SingleListIterator::SingleListIterator(const SingleList &list) : Iterator(list.head)
    {
    }

代码中出现的错误 还有像这种情况下我该怎么办,即两个头文件之间存在相互耦合???? 谢谢


不是这个和你的问题有关,但我会避免使用像 list 这样的命名空间名称,因为这似乎容易引起混淆。我知道当我在问题中看到关于 list::SingleList 的内容时,我的第一个想法是:“std::list 什么时候有一个名为 SingleList 的成员?” - Michael Burr
4个回答

5
你使用前向声明,但仍然递归地包含了.h文件。前向声明的目的是你不需要包含前向声明类的头文件,从而打破相互依赖关系。

此外,只需为其中一个类使用前向声明即可,无需同时为两个类使用。

我建议采用以下结构:

SingleListIterator.h

class SingleList;                // forward declaration
class SingleListIterator {
   // Declarations, only using pointers/references to SingleList.
   // Definitions that need to know the structure of SingleList (like maybe
   // a constructor implementation) need to be done in the .cpp file.
};

SingleList.h:

#include "SingleListIterator.h"  // include full declaration

class SingleList {  
   // declarations
};

SingleListIterator.cpp:

#include "SingleListIterator.h"
#include "SingleList.h"           // include full declaration of the type
                                  // forward-declared in SingleListIterator.h

// method definitions,...

SingleList.h:

#include "SingleList.h"            // include full declarations of everything

// definitions

这样做可以避免文件相互包含,所有类型在实现(.cpp)文件中都是完全已知的。


1
问题是SingleListIterator::SingleListIterator(const SingleList &)构造函数需要知道SingleListhead成员,因此它需要类的完整声明。
你可以:
  1. 将构造函数定义移到单独的源文件中。
  2. 只需包含SingleList.h而不是使用前向声明。只要SingleList.h接受前向声明,你就不需要在SingleListIterator.h中也使用前向声明。
此外,你同时包含了头文件和提供了前向声明。你只需要其中一个(如果你只需要访问类型的成员变量或函数的引用或指针,则坚持使用前向声明)。
总的来说,你正在解决这个问题的正确方向。重要的部分是如果Y.h也必须包括X.h,则X.h不应该包括Y.h。

0

你希望将声明放在头文件中,将定义放在.cpp文件中。

把这段代码放在你的.cpp文件里:

 SingleListIterator::SingleListIterator(const SingleList &list) : Iterator(list.head)
 {
 }

通常情况下,您只需使用前向声明即可使用指针类型。

0

不要从SingleList.h中包含SingleListIterator.h。在SingleList.h中的前向声明已经足够了。你不需要在SingleList.h中定义SingleListIterator

(我假设你已经有某种形式的“包含保护”机制,但在代码片段中省略了它。)
(我会让其他人指出这个片段中所有其他不好的地方。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接