Qt Master Include



  • Servus,

    habe mehrere Klassen die sich kreuz und quer includen. Dadurch bin ich auf einige Probleme gestoßen. Nun würde ich gerne eine große Header-Datei mit sämtlichen Includes haben, die von allen anderen Header-Dateien includet wird. Aufbau dieser Master-Header-Datei:

    #ifndef INCLUDE_H
    #define INCLUDE_H
    
    #include "group.h"
    #include "grouplist.h"
    #include "mainwindow.h"
    #include "person.h"
    #include "personlist.h"
    
    #include <QString>
    #include <QVector>
    #include <QtSql>
    #include <QMessageBox>
    #include <QSplashScreen>
    #include <windows.h>
    #include <QListWidget>
    #include <QDate>
    
    #endif // INCLUDE_H
    

    In jeder anderen Header-Datei steht dann das:

    #include "include.h"
    

    Und dann kommen halt beim Kompilieren so lustige Fehler:

    C:\pgverwaltung-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\pgverwaltung\group.h:12: Fehler:field 'member' has incomplete type
    C:\pgverwaltung-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\pgverwaltung\grouplist.h:8: Fehler:field 'groups' has incomplete type
    C:\pgverwaltung-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\pgverwaltung\grouplist.h:9: Fehler:'QSqlDatabase' does not name a type
    C:\pgverwaltung-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\pgverwaltung\person.h:10: Fehler:'QDate' does not name a type
    C:\pgverwaltung-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\pgverwaltung\person.h:13: Fehler:field 'groups' has incomplete type
    C:\pgverwaltung-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\pgverwaltung\personlist.h:8: Fehler:field 'persons' has incomplete type
    C:\pgverwaltung-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\pgverwaltung\personlist.h:9: Fehler:'QSqlDatabase' does not name a type
    C:\pgverwaltung-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\pgverwaltung\mainwindow.h:10: Fehler:expected class-name before '{' token
    C:\pgverwaltung-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\pgverwaltung\main.cpp:16: Fehler:no matching function for call to 'QSplashScreen::finish(MainWindow*)'
    C:\pgverwaltung-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\pgverwaltung\main.cpp:17: Fehler:'class MainWindow' has no member named 'show'
    

    Kann mir jemand erklären, wie das genau funktioniert?

    Danke im Voraus
    Kk51



  • Ein MegaMasterinclude schafft meist nur mehr Probleme, wie du gerade siehst.
    Was du suchst ist "forward declaration".



  • Auf den Begriff bin ich auch schon gestoßen, allerdings weiß ich nicht recht, wie ich diese Forward Declaration verwenden soll. Hast du vielleicht etwas zum Veranschaulichen? Wobei ich diesesn Master Include wegen der Übersicht vorziehen würde.



  • Eine forwar declaration für eine Klasse Test würde in einer Subdatei einfach so aussehen:

    class Test;
    

    Fertig...Dann kann er nicht mehr behaupten, dass die Klassen nicht existieren oder einen incomplete type haben...Dieser Trick löst aber nur bei bestimmten Architekturen das Problem. Je nachdem wie du das mit dem Masterinclude machst. Wenn es nicht klappt, nochmal fragen 👍



  • Die Reihenfolge der Includes spielt auch eine Rolle.

    Daher würde ich Dir empfehlen, alle fertige Klassen (von Frameworks wie Qt) als erstes hin zu schreiben (bzw. wie Deine Software aufgebaut ist "1. Windows Funktionen", "2. UI Framework", "3. Eigene Implementierung"). Da Du diese nicht selber schreibst aber nutzt.
    Bei einer geschickten Reihenfolge ist die "forward declaration" nicht notwendig (sofern Deine Klassen keine Bi-Direktionale Abhängigkeiten aufweisen).

    Bsp:

    #ifndef INCLUDE_H
    #define INCLUDE_H
    
    // Framework / ext. Libs 
    #include <windows.h>
    
    #include <QString>
    #include <QVector>
    #include <QtSql>
    #include <QMessageBox>
    #include <QSplashScreen>
    #include <QListWidget>
    #include <QDate>
    
    #include "group.h"
    #include "grouplist.h"
    
    #include "person.h"
    #include "personlist.h"
    
    // mainwindows nutzt wohl alle anderen klassen
    #include "mainwindow.h"
    
    #endif // INCLUDE_H
    

    edit2:
    Nur am Rande, von aussen sieht es so aus als würde die "grouplist" und "personlist" identisch sein. Ggf. würde sich es hier anbieten eine Template Klasse zu schreiben.



  • BootLag-BootLag- schrieb:

    Eine forwar declaration für eine Klasse Test würde in einer Subdatei einfach so aussehen:

    class Test;
    

    Fertig...Dann kann er nicht mehr behaupten, dass die Klassen nicht existieren oder einen incomplete type haben...Dieser Trick löst aber nur bei bestimmten Architekturen das Problem. Je nachdem wie du das mit dem Masterinclude machst. Wenn es nicht klappt, nochmal fragen 👍

    Incomplete type haben sie dann immer noch ... zumindestens beim GCC



  • Vielen Dank für die Hilfe. Hatte das Problem zuerst mit sämtlichen Forward Declarations gelöst und lediglich die QClasses ausgelagert. Dann habe ich den Beitrag gelesen, dass die Reihenfolge eine Rolle spielt (was ja durchaus Sinn macht) und jetzt funktioniert es ebenfalls und ist zugleich übersichtlich. Habe zudem die beiden Klassen zusammengeführt, das hat ebenfalls Sinn gemacht. 😉


Anmelden zum Antworten