Typedefs und Klassen - Nicht gefunden



  • Ich habe u.a. 2 Dateien, deren Header das beinhalten:
    ECA.h

    #ifndef __ECA_H__
    #define __ECA_H__
    
    #include "Parameter.h"
    #include <list>
    
    class ECA{
    private:
    	ParamList par;
    //Rest
    };
    
    typedef std::list<ECA> ECAList;
    
    #endif
    

    Parameter.h

    #ifndef __PARAMETER_H__
    #define __PARAMETER_H__
    #include <list>
    #include "ECA.h"
    
    class Parameter;
    
    typedef std::list<Parameter> ParamList;
    
    class Parameter{
    public:
    	ECAList funcs;
            ParamList par;
    //Rest
    };
    #endif
    

    (Die rekursive Struktur lässt sich nicht vermeiden)

    Jetzt habe ich das Problem, dass er in der ECA.h das ParamList und in der Parameter.h das ECAList beim compilieren nicht findet. IntelliSense zeigt es aber an (Bei Hover bzw "Gehe zu definition")

    Sollte der typedef das nicht für alles deklarieren? Die Dateien werden doch wechselseitig eingebunden, sind also offensichtlich vorhanden.



  • Flamefire schrieb:

    (Die rekursive Struktur lässt sich nicht vermeiden)

    Dann kannst du es nur mit Zeigern/Referenzen und Forwarddeklaration lösen. Ein wechselseitig inkludieren ist nicht möglich!



  • das Konstrukt an sich funktioniert. Wenn ich die typedefs der map in der jeweils anderen Datei weiderhole, klappt auch alles (compiliert und funktioniert)
    Dass er nicht in einer endlosschleife von includes landet, verhindern die compiler-directiven

    Aber ich wundere mich eben, dass er anscheinend das typedef "übersieht".



  • in parameter.h steht nach dem include von eca.h sinngemäß folgendes:

    #ifndef __PARAMETER_H__
    #define __PARAMETER_H__
    
    #include <list> //lass ich mal so..
    
    // begin #include eca.h
      #ifndef __ECA_H__
      #define __ECA_H__
    
      //begin #include parameter.h
        #ifndef __PARAMETER_H__ //ist schon definiert. ende.
        #endif
      //end #include parameter.h
      //entfällt wegen include-guards: #include <list>
    
      class ECA{
      private:
          ParamList par; //FEHLER! was ist paramlist??
      //Rest
      };
    
      typedef std::list<ECA> ECAList;
    
      #endif //__ECA_H__
    //end #include eca.h
    
    class Parameter;
    
    typedef std::list<Parameter> ParamList;
    
    class Parameter{
    public:
        ECAList funcs;
            ParamList par;
    //Rest
    };
    #endif // __PARAMETER_H__
    

    Andersrum ist sinngemäß ECAList nicht definiert..



  • stimmt. Dann macht die Meldung auch sinn.
    Aber wie kann ich das ganze beheben?
    Eine Möglichkeit wäre ja jeweils eine Vorwärstdeklration auf den Typ der List, dann die List deklarieren und dann den Include. Danach den Rest wie gehabt.
    Ist aber etwas unsauber.



  • Nein. Im Header Vorabdeklaration, Includen in der .cpp.



  • Flamefire schrieb:

    Aber wie kann ich das ganze beheben?

    So ähnlich wie du es gemacht hast - wenn überhaupt.
    Es kann sein, dass die Benutzung von std::list verlangt, dass der Argument-Typ vollständig definiert ist, dann gehts so garnicht und du musst mit Referenzen arbeiten. Bei std::vector ist das der Fall, bei std::list weiß ichs nicht.
    Falls forward-Deklarationen reichen machs so:

    //eca.h
    #ifndef ECA_H_ //bezeichner mit doppelten Unterstrichen sind reserviert!
    #define ECA_H_ //bezeichner die mit Unterstrich+Grossbuchstabe beginnen auch
    
    #include <list>
    class Parameter;
    
    class ECA
    {
      typedef std::list<Parameter> ParamList;
      ParamList par;
    };
    #endif
    
    /**********************************/
    //parameter.h
    #ifndef PARAMETER_H_ //s.o.
    #define PARAMETER_H_
    
    #include <list>
    class ECA;
    
    class Parameter
    {
      typedef std::list<ECA> ECAList;
      typedef std::list<Parameter> ParamList;
    
      ECAList funcs;
      ParamList par;
    };
    #endif
    

    Hat zum Vorteil, dass du mit den typedefs nicht den globalen namensraum vollmüllst.



  • Ok mache ich.
    BTW: Es funktioniert ja auch mit den Klassen, nicht nur mit den Pointern. MemLeaks gibts da lt VS auch nicht.

    Zu den defines:
    Die Konvention hatte ich aus einem Tutorial vor ner Weile...
    Na gut, dann so.
    Da gibt es doch aber auch noch "#pragma once"
    Ist weniger aufwand und mehr Übersicht.

    Hat das einen Nachteil, weshalb ich es nicht nehmen sollte?



  • Flamefire schrieb:

    Ok mache ich.
    BTW: Es funktioniert ja auch mit den Klassen, nicht nur mit den Pointern.

    Was aber nicht für jeden Containertyp funktionieren müsste (Ggf. sogar von der konkreten Umsetzung der std::list abhängig ist - will jetzt dafür nicht im C++ Standard suchen).

    Flamefire schrieb:

    Da gibt es doch aber auch noch "#pragma once"
    Ist weniger aufwand und mehr Übersicht.

    Ist aber Compilerabhängig.


Anmelden zum Antworten