Auch Klassenverwirrung



  • Hallo,
    Ich habe so ein ähnliches Problem wie im Beitrag eben.
    Ich habe alle Klassen in Header-Datei und CPP-Datei unterteilt:

    CPP-Datei:

    #include "SIGIContainer.h"
    SIGIContainer::SIGIContainer()
     {
     }
    

    Header - Datei:

    #ifndef SIGICONTAINERH
    #define SIGICONTAINERH
    
    class SIGIContainer
    {
     public:
      SIGIContainer();
      ~SIGIContainer();
    };
    
    #endif
    

    Soweit funktioniert das alles: Ich möchte jetzt aber SIGIContainer von SIGIObject, einfach einer anderen Klasse ableiten.

    Ich habe die Header-Datei von SIGIObject eingebunden und die Ableitung hingeschrieben.
    Außerdem möchte ich, daß in SIGIContainer eine Liste von SIGIObject existiert.
    Das sieht dann so aus:

    #ifndef SIGICONTAINERH
    #define SIGICONTAINERH

    #include "SIGIObject.h"

    class SIGIContainer: public SIGIObject
    {
    vector <SIGIObject*> children;
    public:
    SIGIContainer();
    ~SIGIContainer();
    };

    #endif

    Jetzt kommt aber der Fehler, daß er hier den Typ SIGIObject nicht mehr erkennt und alles beim kompilieren abbricht.

    Was ist denn der Fehler ?????

    Danke



  • Ich habe so ein ähnliches Problem wie im Beitrag eben.

    Ach so. Ja klar. In welchem Beitrag auch sonst. Wir haben ja nur ein paar tuasend.
    Ein Link wäre nett.

    Was ist denn der Fehler ?????

    Du verwendest in SIGIObject.h aus versehen auch SIGICONTAINERH als Includeguard. Keine Ahnung. Woher soll ich das denn wissen? Schreib doch mal dazu, was der Compiler dazu meint. Vielleicht kann ich die Meldung ja für dich interpretieren oder Schlüsse ziehen, zu denen du noch nicht in der Lage bist. Aber ohne Informationen kann ich dir nicht helfen.



  • SIGIObject.h sieht so aus:

    #ifndef SIGIOBJECTH
    #define SIGIOBJECTH
    
    #include "SIGIContainer.h"
    
    class SIGIObject
    {
     private:
      SIGIContainer *parent;
     public:
      SIGIObject();
    };
    #endif
    

    Er meldet mir in der Datei SIGIContainer.h an folgender Zeile:

    class SIGIContainer: public SIGIObject
    

    den Fehler:
    Type name exspected.



  • nur so als Anmerkung weil ich das letztens öfters sehe:
    Was sollen diese Prefixe ala SIGI, ABC, PUHBAER und SCHNAEUZELCHEN?

    Dafür gibt es namespaces



  • Autsch

    SIGIObject.h definiert zunächst seinen Includeguard, bindet dann SIGIContainer ein.h ein. Dieser versucht SIGIObject.H einzubinden, was aber quasi nicht gemacht wird, da der Includequard davor schützt. Dann wird aber rotzdem versucht die Klasse SIGIObject zu verwenden, was nicht geht, weil sie noch nicht definiert und auch nicht deklariert wurde.

    Lass deine SIGIObject.h mal so ausehen:

    #ifndef SIGIOBJECTH
    #define SIGIOBJECTH
    
    class SIGIContainer;
    
    class SIGIObject
    {
     private:
      SIGIContainer *parent;
     public:
      SIGIObject();
    };
    #endif
    

    Und dann hör noch auf Shade!



  • Also, ich probiere es nochmal:

    also ich habe
    header Datei b.h:

    #ifndef BHH
    #define BHH
    
    #include "a.h"
    
    class b:public a      //<-- type name expected !!!!
    {
     int ii;
     public:
     int f();
    };
    
    #endif
    

    und header-datei a.h:

    #ifndef AHH
    #define AHH
    
    #include "b.h"
    
    class a
    {
     int i;
     class b *x;
     public:
     int f();
    };
    
    #endif
    

    Warum kommt in der vorgehobenen Zeile ein Fehler ????



  • ...



  • Zwei Klassen sind
    - b soll von a alles erben
    - a soll ein feld vom typ b haben
    - b soll ein feld vom typ a haben
    - und alles getrennt in dateien

    mehr nicht



  • Helium hat es schon erklärt:

    Was macht der Preprozesser beim Compilieren von A?
    Er ersetzt das #include "b.h" durch den Inhalt von b.h

    #ifndef AHH
    #define AHH
    
    #ifndef BHH
    #define BHH
    
    #include "a.h"
    
    class b:public a      //<-- type name expected !!!!
    {
     int ii;
     public:
     int f();
    };
    
    #endif
    class a
    {
     int i;
     class b *x;
     public:
     int f();
    };
    
    #endif
    

    Und jetzt wird das #include "a.h" durch den Inhalt von a.h ersetzt:

    #ifndef AHH
    #define AHH
    
    #ifndef BHH
    #define BHH
    
    #ifndef AHH
    #define AHH
    
    #include "b.h"
    
    class a
    {
     int i;
     class b *x;
     public:
     int f();
    };
    
    #endif
    
    class b:public a      //<-- type name expected !!!!
    {
     int ii;
     public:
     int f();
    };
    
    #endif
    class a
    {
     int i;
     class b *x;
     public:
     int f();
    };
    
    #endif
    

    Das könnte nun endlos so weitergehen, aber Du hast einen Guard eingebaut:

    #ifndef AHH
    #define AHH
    ...
    #endif
    

    Und da AHH schon weiter oben definiert wurde. Fällt der ganze Bereich raus:

    #ifndef AHH
    #define AHH
    
    #ifndef BHH
    #define BHH
    
    class b:public a      //<-- type name expected !!!!
    {
     int ii;
     public:
     int f();
    };
    
    #endif
    class a
    {
     int i;
     class b *x;
     public:
     int f();
    };
    
    #endif
    

    Und jetzt siehst Du, dass dort wo der Fehler auftritt a noch gar nicht definiert ist.
    Lösung:
    schreib statt:

    #include "b.h"
    

    einfach eine Vorwärsdeklaration:

    class b;
    


  • Jau,

    volltreffer, das wars, danke !



  • volltreffer, das wars, danke !

    Ja, ich weiß, hab ich dir auch von anfang an geschreiben.



  • Der Beitrag mit den Namespaces war trotzdem sehr weiterbringend !!!!



  • Der Beitrag mit den Namespaces war trotzdem sehr weiterbringend !!!!

    Ja, aber durchaus sinnvoll und ernst gemeint.

    // "sigi/object.hpp"
    namespace Sigi {
       class Object {
          ...
       };
    }
    
    // "sigi/container.hpp"
    namespace Sigi {
       class Container {
          ...
       };
    }
    
    // foo.cpp
    
    #include "sigi/container.hpp"
    
    int main ()
    {
       Sigi::Container mein_Container;
    }
    
    /* oder
    
    using namespace Sigi;
    
    int main ()
    {
       Container mein_Container;
    }
    */
    

Anmelden zum Antworten