Предварительное объявление 'const struct list :: SingleList', Недопустимое использование неполного типа 'list :: SingleList' (Ошибки компиляции) - PullRequest
3 голосов
/ 24 февраля 2010

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)
    {
    }

Ошибки, указанные в коде И что я могу сделать в таком случае, когда существует взаимная связь между двумя заголовочными файлами?????Thaaaaanks

Ответы [ 4 ]

5 голосов
/ 24 февраля 2010

Вы используете предварительные объявления, но вы все равно включаете файлы .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 голос
/ 24 февраля 2010

Проблема в том, что конструктору SingleListIterator::SingleListIterator(const SingleList &) нужно знать о head члене SingleList, поэтому ему нужно полное объявление класса.

Вы можете:

  1. Переместить определение конструктора в отдельный исходный файл.
  2. Просто включите SingleList.h вместо использования предварительного объявления. Пока SingleList.h в порядке с предварительным объявлением, вам также не нужно использовать его в SingleListIterator.h.

Кроме того, вы оба включаете заголовочные файлы и предоставляете предварительные объявления. Вам нужен только один или другой (придерживайтесь прямого объявления, если вам нужны только ссылки или указатели на тип и нет доступа к переменным или функциям-членам типа).

Вы на правильном пути к решению этой проблемы в целом. Важной частью является то, что X.h не включает Y.h, если Y.h также должен включать X.h.

0 голосов
/ 24 февраля 2010

Не включать SingleListIterator.h из SingleList.h. Предварительного объявления для него в SingleList.h достаточно. Вам не нужно определение SingleListIterator в SingleList.h.

(я предполагаю, что у вас есть какое-то «включенное ограждение», которое вы пропустили во фрагменте). (Я позволю всем остальным указать на все другие вещи, которые плохи в этом фрагменте.)

0 голосов
/ 24 февраля 2010

Вы хотите разделить вашу декларацию на заголовочные файлы и ваше определение на .cpp файлы.

Поместите это в ваш .cpp:

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

Как правило, вы всегда можете использовать тип указателя, просто имея прямое объявление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...