[C++] Klassen untereinander referenzieren.

  • Als ich heute an diesem wunderschönen Morgen (grau und Regen) aufstand und mich an eine kleines Projekt machen wollte, merkte ich, dass ich wiedereinmal den Wald vor Lauter Bäumen nicht sehe ...

    Ich versuche aus Gründen der Einfachheit mehrere Klassen untereinander zu verlinken.
    Dazu habe ich eine Klasse (cKernel) die auf alle Klassen referenziert und auf die alle Klassen referenzieren.
    Das funktioniert auch wunderbar, nur kann ich leider, sofern ich der Kernelklasse eine der andere übergeben habe, nicht darauf zugreifen ...

    Es folgen die Codes der Datei (alles unwichtige weggelassen),
    Folgendes bezieht sich nur auf die Referenzierunf von Kernel und MainFrame, da der Fehler bei allen anderen Klassen derselbe ist.

    main.cpp

    kernel.h

    kernel.cpp

    mainFrame.h

    Das ganze funktioniert auch relativ gut.
    Allerdings bekomme ich bei dem Befehl MainFrame->OnFullScreen(); (Bei this->MainFrame->OnFullScreen(); passiert dasselbe.) folgende Ausgabe.

    Zitat


    kernel.cpp||In member function »void cKernel::RegisterMainFrame(cMainFrame*)« : |
    kernel.cpp|72|Fehler: invalid use of undefined type »struct cMainFrame«|
    kernel/kernel.h|34|Fehler: forward declaration of »struct cMainFrame«|
    ||=== Build finished: 2 errors, 0 warnings ===|

    Wenn ich den obengenannten Befehl weglasse, wird es anstandslos kompiliert.

    OS: Ubuntu Linux 64 Bit
    IDE: Code::Blocks
    FW: wxWidgets
    GCC: 4.1.2-16ubuntu2 (gutys)
    CPP: 4.1.2-16ubuntu2 (gutsy)

    Hat jemand eine Idee, wie man das Problem lösen kann ??

  • Du nutzt in der Header Datei Vorwärtsdeklaration um dort keine Includes nutzen zu müssen. Schöne Sache (mach ich auch so), aber ich glaube du hast vergessen in der kernel.cpp die mainFrame.h zu includen.

    Jetzt weiß der Compiler zwar das es cMainFrame gibt, und kann die Zeigeroperationen ausführen (die Zuweisung) da alle Zeigeradressen 32 bzw. 64 Bit groß sind, aber der Methodenaufruf geht schief -> er weiß ja nicht welche Methoden für cMainFrame überhaupt existieren.

  • In welcher Hinsicht ein Overhead?
    Du musst die Headerdatei includen, sonst weiß der Compiler ja nicht was das für eine Struktur/Klasse ist (also welche Funktionen, Methoden und Member). Du kannst sonst nicht damit arbeiten.

  • Ja ist mir klar, aber so werden sie ja teilweise doppelt includiert.
    Der Compiler erstellt ja aus jeder .cpp Datei eine .o Datei und linkt das dann.
    Demnach müsste ja, wenn ich die Datei mainFrame.h in 2 verschiedenen .cpp Datein includiere der Code ja in beiden .o Datein mit drin sein.

    Wenn nun der Linker die .os verlinkt, schmeisst er dann die doppelten Informationen raus?

  • Halt, du verwechselst hier gerade Definition und Deklaration. In der Header Datei stehen (normalerweise) nur die Definitionen deiner Klassen und deren Methoden/Membervariablen. Dort steht kein ausführbarer Code (Deklaration).
    Der Compiler braucht die Definition für jede Objektdatei (.o) um zu wissen, was er mit einer Instanz machen kann. Die Definition der Klasse steht am Ende nicht in der Objektdatei.

    Natürlich hast du beispielsweise bei Templates, bei der die Deklaration in der Headerdatei drin stehen muss um während der Compilezeit den Code erstellen zu können, Redundanzen. Weiß jetzt aber nicht ob die eventuell wegoptimiert werden. Das müsste dann im Linker geschehen.

    Und Vorwärtsdeklaration von Klassen in Headerdateien beschleunigen einfach den Compiliervorgang, weil der Compiler nicht für jede Objektdatei 100te Header parsen muss.