2010-02-23 3 views
3

SingleList.hdéclaration avant de la 'liste struct const :: SingleList', utilisation non valide de type incomplet 'liste :: SingleList' (erreurs de compilation)

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

Erreurs indiquées dans le code Aussi, que puis-je faire dans un cas comme celui-ci où il y a un couplage mutuel entre deux fichiers d'en-tête ????? Thaaaaanks

+0

Cela ne veut pas dire que cela a quelque chose à voir avec votre problème, mais j'éviterais un nom d'espace de nommage comme 'list' car il semble que cela puisse prêter à confusion. Je sais que lorsque j'ai vu des choses dans la question à propos de 'list :: SingleList', ma première pensée était quelque chose comme:« Depuis quand 'std :: list' a-t-il un membre nommé' SingleList'? –

Répondre

5

Vous utilisez des déclarations directes, mais vous incluez les fichiers .h de manière récursive. Le point des déclarations directes est que vous n'avez pas besoin d'inclure les en-têtes de la classe déclarée en avant , brisant ainsi la dépendance mutuelle.

En outre, il devrait être suffisant d'utiliser une déclaration en avant pour une des classes, pas pour les deux d'entre eux.

Je suggère la structure suivante:

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 

De cette façon, il n'y a pas de fichiers qui comprennent mutuellement et tous les types sont complètement connus dans les fichiers d'implémentation (.cpp).

0

Vous souhaitez séparer votre déclaration en fichiers d'en-tête et votre définition en fichiers .cpp.

Mettre ce dans votre Cpp:

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

En règle générale, vous pouvez aussi toujours utiliser un type de pointeur avec juste avoir la déclaration avant.

1

Le problème est que le constructeur SingleListIterator::SingleListIterator(const SingleList &) doit connaître le membre head de SingleList, il a donc besoin de la déclaration complète de la classe.

Vous pouvez:

  1. Déplacer la définition du constructeur à un fichier source séparé.
  2. Incluez simplement SingleList.h au lieu d'utiliser une déclaration forward. Tant que SingleList.h est correct avec une déclaration forward, vous n'avez pas besoin d'en utiliser une dans SingleListIterator.h.

De plus, vous incluez tous les deux les fichiers d'en-tête ET fournissez des déclarations directes. Vous n'avez besoin que de l'un ou de l'autre (respectez une déclaration forward si vous avez seulement besoin de références ou de pointeurs sur le type et pas d'accès aux variables ou fonctions membres du type).

Vous êtes sur la bonne voie pour résoudre ce problème en général. La partie importante est que X.h n'inclut pas Y.h si Y.h doit aussi inclure X.h.

0

N'incluez pas SingleListIterator.h de SingleList.h. La déclaration directe pour cela dans SingleList.h est suffisante. Vous n'avez pas besoin de la définition de SingleListIterator dans SingleList.h.

(je suppose que vous avez une sorte de « inclure la garde » à la place que vous avez omis dans l'extrait.)
(Je vais laisser tout le monde lui signaler tous les autres choses qui sont pauvres à propos de cet extrait.)