3 Stimmen

Forward-Deklaration von 'const struct list::SingleList' , Ungültige Verwendung des unvollständigen Typs 'list::SingleList' (Kompilierungsfehler)

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

Im Code angezeigte Fehler Und was kann ich in einem Fall wie diesem tun, in dem eine gegenseitige Kopplung zwischen zwei Header-Dateien besteht ????? Vielen Dank

5voto

sth Punkte 210180

Sie verwenden Forward-Deklarationen, aber Sie schließen trotzdem die .h Dateien rekursiv. Der Sinn der Forward-Deklarationen ist, dass Sie die Header der deklarierten Klasse einbinden müssen, wodurch die gegenseitige Abhängigkeit aufgehoben wird.

Es sollte auch genügen, eine Forward-Deklaration zu verwenden für un der Klassen, nicht für beide.

Ich würde die folgende Struktur vorschlagen:

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

Auf diese Weise gibt es keine Dateien, die sich gegenseitig einschließen, und alle Typen sind in den Implementierungsdateien (.cpp) vollständig bekannt.

1voto

Nick Meyer Punkte 37405

Das Problem ist, dass die SingleListIterator::SingleListIterator(const SingleList &) Konstruktor muss über die head Mitglied von SingleList und benötigt daher die vollständige Deklaration der Klasse.

Sie können:

  1. Verschieben Sie die Konstruktordefinition in eine separate Quelldatei.
  2. Schließen Sie einfach SingleList.h ein, anstatt eine Vorwärtsdeklaration zu verwenden. Solange SingleList.h mit einer Vorwärtsdeklaration einverstanden ist, müssen Sie nicht auch eine in SingleListIterator.h verwenden.

Außerdem schließen Sie sowohl die Header-Dateien als auch die Forward-Deklarationen mit ein. Sie brauchen nur das eine oder das andere (bleiben Sie bei einer Forward-Deklaration, wenn Sie nur Referenzen oder Zeiger auf den Typ benötigen und keinen Zugriff auf die Member-Variablen oder Funktionen des Typs).

Sie sind auf dem richtigen Weg, dieses Problem generell zu lösen. Der wichtige Teil ist, dass X.h nicht Y.h enthält, wenn Y.h auch X.h enthalten muss.

0voto

Brian R. Bondy Punkte 325712

Sie möchten Ihre Deklaration in Header-Dateien und Ihre Definition in .cpp-Dateien aufteilen.

Fügen Sie dies in Ihre .cpp ein:

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

In der Regel können Sie auch immer einen Zeigertyp verwenden, wenn Sie nur die Forward-Deklaration haben.

0voto

Nicht einbeziehen SingleListIterator.h von SingleList.h . Die Forward-Deklaration für sie in SingleList.h ist ausreichend. Sie brauchen nicht die Definition von SingleListIterator en SingleList.h .

(Ich gehe davon aus, dass Sie eine Art "Include Guard" eingerichtet haben, die Sie in dem Schnipsel weggelassen haben).
(Ich überlasse es den anderen, auf die vielen otros Dinge, die an diesem Schnipsel schlecht sind).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X