gegenseitiges includieren



  • Hallo zusammen,

    ich schreib im Moment an meiner Diplomarbeit und habe da ein (ich hoffe) kleines Problem bei einer C++-Geschichte.

    Vereinfacht sieht das Problem so aus: Ich habe zwei .cpp-Dateien mit den zugehörigen .h-Dateien.

    Erstens die finite_state_machine.cpp und diese includiert die finite_state_machine.h. Die finite_state_machine.h
    sieht ungefähr so aus:

    // finite_state_machine.h
    #ifndef _FINITE_STATE_MACHINE_H
    #define _FINITE_STATE_MACHINE_H

    #include "superstate.h"

    class finite_state_machine {
    // .... Klassenkram...
    };

    #endif /* _FINITE_STATE_MACHINE_H */

    Dabei wird das #include "superstate.h" benötigt, weil ich in der Klassenimplementierung (finite_state_machine.cpp)
    ein Objekt der Klasse superstate instanziiere und (das ist wohl der Punkt) auf eine Methode zugreife:

    // in einer Methode in finite_state_machine.cpp
    superstate* superstatepointer;
    superstatepointer->step();

    Die Klasse superstate erbt unter anderem die finite_state_machine - daher das #include "finite_state_machine.h".
    Die Klassendeklaration von superstate sieht so aus (in superstate.h):

    // superstate.h
    #ifndef _SUPERSTATE_H
    #define _SUPERSTATE_H

    #include "finite_state_machine.h"

    class superstate : public state : public finite_state_machine {
    // .... Klassenkram...
    };

    Nun gibts Probleme beim kompilieren, da wenn finite_state_machine.h verarbeitet wird zunächst superstate.h includiert wird.
    Dabei brichts dann ab, da das " : public finite_state_machine " aufgrund der Unbekanntheit von finite_state_machine noch nicht
    klappen kann. Der nun übliche Weg der Vorwärtsdeklaration von finite_state_machine in superstate.h per
    class finite_state_machine; funktioniert auch nicht. Es gibt dann einen Fehler "finite_state_machine has incomplete type".
    Wenn ich die Deklarationen aus den .h's in die finite_state_machine.h zusammenpacke (zuerst für finite_state_machine und dann für superstate) und vor
    dem ganzen class superstate; vorwärts deklariere - dann anstatt superstate.h finite_state_machine.h in der superstate.cpp includiere geht es.

    Das kann wohl nicht sein - gibt es da auch eine saubere Lösung !?
    Ich hoffe Euch nicht zu sehr verwirrt zu haben.

    vielen Dank

    Michael



  • Dabei wird das #include "superstate.h" benötigt, weil ich in der Klassenimplementierung (finite_state_machine.cpp)
    ein Objekt der Klasse superstate instanziiere und (das ist wohl der Punkt) auf eine Methode zugreife:

    // in einer Methode in finite_state_machine.cpp
    superstate* superstatepointer;
    superstatepointer->step();
    

    Hier liegt der Schluessel zu deinem Problem. Nutze in finite_state_machine einen
    Zeiger auf ¨superstate¨ und mache eine Vorwaertsdeklaration von ¨superstate¨ in
    finite_state_machine. Die include-Anweisung ¨superstate.h¨ entfernst du.

    Jetzt sollte es funktionieren.

    Ich hoffe Euch nicht zu sehr verwirrt zu haben.

    Informatiker oder Mathematiker? Dann ist es dein Job, andere zu verwirren 😉

    mfg
    v R



  • Unter dem Stichwort forward-Declaration (class x;) solltest du das passende
    finden. 😉



  • vielen Dank für Eure Antworten.

    @virtuell Realisticer:
    Den Zeiger auf ¨superstate¨ benutze ich mit

    // in einer Methode in finite_state_machine.cpp
    superstate* superstatepointer;
    superstatepointer->step();

    ja doch schon. Oder verstehe ich Dich falsch ?
    Nebenbei: Ich bin kein Mathematiker / Informatiker (sondern Maschinenbauer).

    Was zu (komischerweise) auch funktioniert ist, alle Vorwärtsdeklarationen wegzulassen und normal gegenseitig includieren. Dabei jedoch das #include "superstate.h" in der finite_state_machine.h erst nach der Deklaration der Klasse finite_state_machine zu schreiben.

    Vielleicht geht's besser und ich wüsst schon gern wie. So ist es aber erst einmal erträglich da die Deklarationen wieder in den .h's stehen wo sie hingehören.



  • michaelproto schrieb:

    vielen Dank für Eure Antworten.

    @virtuell Realisticer:
    Den Zeiger auf ¨superstate¨ benutze ich mit

    // in einer Methode in finite_state_machine.cpp
    superstate* superstatepointer;
    superstatepointer->step();

    ja doch schon. Oder verstehe ich Dich falsch ?
    Nebenbei: Ich bin kein Mathematiker / Informatiker (sondern Maschinenbauer).

    Was zu (komischerweise) auch funktioniert ist, alle Vorwärtsdeklarationen wegzulassen und normal gegenseitig includieren. Dabei jedoch das #include "superstate.h" in der finite_state_machine.h erst nach der Deklaration der Klasse finite_state_machine zu schreiben.

    Vielleicht geht's besser und ich wüsst schon gern wie. So ist es aber erst einmal erträglich da die Deklarationen wieder in den .h's stehen wo sie hingehören.

    Ich meinte das so:

    #ifndef _FINITE_STATE_MACHINE_H
    #define _FINITE_STATE_MACHINE_H
    
    class superstate;
    
    class finite_state_machine {
    // .... Klassenkram...
    //irgendwo superstate* instance oder sowas
    };
    
    #endif /* _FINITE_STATE_MACHINE_H */
    

    Und nun kann man das problemlos includieren:

    #ifndef _SUPERSTATE_H
    #define _SUPERSTATE_H
    
    #include "finite_state_machine.h"
    
    class superstate : public state : public finite_state_machine {
    // .... Klassenkram...
    };
    

    Falls du ein superstate* nur in einer Elementfunktion von finite_state_machine
    benoetigst, dann musst du hier nicht mal die vorwaertsdeklaration machen,
    sondern "superstate.h" lediglich in der "finite_state_machine.cpp" includieren.

    mfg
    v R


Anmelden zum Antworten