Invalid use of incomplete Type (in Qt)



  • Hallo!
    Ich arbeite im Zuge meines Studiums an einem Programmierpraktikum (Sudoku graphisch in Qt) und sitze seit 3 Tagen schon an einem Fehler den ich einfach nicht korrigieren kann (und verstehe 😉 )

    Ich habe bereits gesucht und natürlich dazu auch schon Treffer gefunden jedoch verstehe ich schlichtweg die Antwort nicht!
    Das Problem liegt wsl auch darin, dass alles funktioniert hatte bis ich irgendetwas ändern wollte und dann nix mehr ging 😞

    Zu meinem Projekt: (gliedert sich auf in main.cpp, sudoku.cpp, fehler.cpp, und gewonnen.cpp ,die Headerfiles: sudoku.h, fehler.h,gewonnen.h sowie die .ui-files: sudoku.ui, fehler.ui, gewonnen.ui)

    main.cpp
    --------

    #include <QtGui/QApplication>
    #include <sudoku.h>
    #include <fehler.h>
    #include <gewonnen.h>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Sudoku w;
        w.show();
    
        return a.exec();
    }
    

    sudoku.cpp
    ----------

    #include <sudoku.h>
    #include <ui_sudoku.h>
    #include <fehler.h>
    #include <gewonnen.h>
    
    Sudoku::Sudoku(QWidget *parent): QMainWindow(parent), ui(new Ui::Sudoku)
    {
     ui->setupUi(this);
     /---/
    }
    
    // andere Funktionen deklariert
    
    Sudoku::~Sudoku()
    {
     delete ui;
    }
    
    sudoku.h
    --------
    
    [cpp]
    #ifndef SUDOKU_H
    #define SUDOKU_H
    
    #include <QMainWindow>
    #include <QtGui>
    
    namespace Ui {
        class Sudoku;
    }
    
    class Sudoku : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit Sudoku(QWidget *parent = 0);
        ~Sudoku();
    
    private slots:
        // hab ich jetzt wegelassen, alle flt aus sudoku.cpp
    
    private:
        Ui::Sudoku *ui;
        std::vector<std::vector<int> > A;
        QGridLayout *lay;
    
    };
    
    #endif // SUDOKU_H
    

    fehler.h
    --------

    #ifndef FEHLER_H
    #define FEHLER_H
    
    #include <QDialog>
    
    namespace Ui {
        class fehler;
    }
    
    class Sudoku : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit fehler(QWidget *parent = 0);
        ~fehler();
    
    private:
        Ui::Sudoku *uif;
    
    };
    
    #endif // FEHLER_H
    

    gewonnen.h sieht bis auf die Namensänderungen genauso aus!

    Wie gesagt die Fehlermeldung sieht wie folgt aus:

    in constructor 'Sudoku::Sudoku(QWidget*)
    - invalid use of incomplete type 'struct Ui::Sudoku'
    - forward declaration of 'struct Ui::Sudoku'

    Vielen Dank für eure Mühe, ich hoffe ihr könnt mir bei der Fehlersuche helfen 😉



  • kleiner Nachtrag:

    Sollte es etwas mit Inkludierung zu tun haben:

    die files: fehler.cpp und gewonnen.cpp inkludieren stehts <ui_fehler.h> bzw <ui_gewonnen.h> sowieso <fehler.h> bzw. <gewonnen.h>



  • Dein Compiler kennt an der Fehlerstelle nur die Vorwärtsdeklaration von Ui::Sudoku, nicht aber die Klassendefinition. Entweder es fehlt der entsprechende Header, oder du hast den Klassennamen nicht überall gleich geschrieben (groß/klein).



  • Ok, also das hab ich überprüft da stimmt alles!

    Nur damit ich das richtig verstehe, die Forward-Deklaration ist dann in der sudoku.h-datei: Ui::Sudoku *ui; oder?
    Oder ist das die Klassendefinition?

    Wie gesagt ich bin kein Informatiker sondern habe außer einem Programmierkurs in c++ nie objektorientiert programmiert 😞


  • Mod

    Dein Problem ist, dass du eine Klasse Ui::Sudoku Forward-deklarierst (und auch benutzt), diese wird aber nirgendwo konkret definiert.



  • Ok 😕 😉

    Also meine Frage wäre dann wieso es bei fehler.cpp, gewonnen.cpp keinen Fehler gibt da ich es dann dort auch nicht definieren!
    Muss diese Deklaration dann in Sudoku.h?

    Also tut mir leid wenn ich davon jetzt keine Ahnung habe!


  • Mod

    Nille88 schrieb:

    Ok, also das hab ich überprüft da stimmt alles!

    🙄 Wenn alles stimmen würde, dannn würden ja wohl weder wir noch der Compiler das Gegenteil behaupten. Wem glaubst du mehr, deinen eigenen Fähigkeiten oder dem Rest der Welt?

    Nur damit ich das richtig verstehe, die Forward-Deklaration ist dann in der sudoku.h-datei: Ui::Sudoku *ui; oder?
    Oder ist das die Klassendefinition?

    Weder noch. Wenn du Wörter nicht verstehst, dann schlag sie nach. Und lern die Grundlagen von Klassen. Die Foward-Deklaration steht hier im Forum in Zeile 30. Eine Defintion hast du wie gesagt gar nicht.

    Wie gesagt ich bin kein Informatiker sondern habe außer einem Programmierkurs in c++ nie objektorientiert programmiert 😞

    Informatiker programmieren nicht (unbedingt). Aber man sieht, dass duu Schwierigkeiten mit objektorientierung hast. Vielleicht erst einmal Grundlagen lernen undeinfache Beispiele machen? Sonst endest du wie der berüchtigte Programmierbuchautor Jürgen Wolf und programmierst, dass ein Supermarkt eine Wurst ist. Du hast hier in deinem Programm praktisch schon behauptet, dass ein Sudoku ein Fenster ist.


  • Mod

    Nille88 schrieb:

    Also meine Frage wäre dann wieso es bei fehler.cpp, gewonnen.cpp keinen Fehler gibt da ich es dann dort auch nicht definieren!
    Muss diese Deklaration dann in Sudoku.h?

    Meistens reicht eine Forward-Deklaration, also die Kenntnis, dass eine Klasse mit diesem Namen existiert. Erst wenn du ein Objekt konkret benutzt, muss der Compiler wissen, wie es genau aussieht und braucht die Definition. Wenn du in diesen Dateien nur Zeiger oder Referenzen auf ui:Sudoku benutzt, dann reicht die Forward-Deklaration.



  • Nille88 schrieb:

    Ok 😕 😉

    Also meine Frage wäre dann wieso es bei fehler.cpp, gewonnen.cpp keinen Fehler gibt da ich es dann dort auch nicht definieren!
    Muss diese Deklaration dann in Sudoku.h?

    Also tut mir leid wenn ich davon jetzt keine Ahnung habe!

    Woher sollen wir das wissen? Du hast den Code ja nicht gezeigt. Wenn du dort jedoch auf Ui::Sudoku zugreifst, machst du auf jeden Fall etwas falsch.

    Nach Qt-Logik müsste die Klasse jedenfalls in ui_sudoku.h definiert werden.



  • Ja wie gesagt bin neu im Qt-Programmieren!

    Was mir eben nicht so klar ist, es lief ja alles wunderbar bis ich irgendetwas in sudoku.cpp verändert habe! Und wenn die Deklaration in fehler.h oder gewonnen.h falsch wäre dann hätte es dort aber vorher ja auch schon einen Fehler geben (da ich nach dem Fehler dort nichts verändert habe!) jedoch ist der Aufbau ja gleich!

    Im file ui_sudoku.h habe ich nichts verändert, da es laut den Hinweisen automatisch generiert wird!

    #ifndef UI_SUDOKU_H
    #define UI_SUDOKU_H
    
    #include <QtCore/QVariant>
    #include <QtGui/QAction>
    #include <QtGui/QApplication>
    #include <QtGui/QButtonGroup>
    #include <QtGui/QHeaderView>
    #include <QtGui/QMainWindow>
    #include <QtGui/QWidget>
    #include <QGridLayout>
    
    QT_BEGIN_NAMESPACE
    
    class Ui_sudoku
    {
    public:
        QWidget *fenster;
    
        void setupUi(QMainWindow *Sudoku)
        {
            if (Sudoku->objectName().isEmpty())
                Sudoku->setObjectName(QString::fromUtf8("sudoku"));
            Sudoku->resize(800, 600);
            fenster = new QWidget(Sudoku);
            fenster->setObjectName(QString::fromUtf8("fenster"));
            Sudoku->setCentralWidget(fenster);
    
            retranslateUi(Sudoku);
    
            QMetaObject::connectSlotsByName(Sudoku);
        } // setupUi
    
        void retranslateUi(QMainWindow *Sudoku)
        {
            Sudoku->setWindowTitle(QApplication::translate("Sudoku", "MainWindow", 0, QApplication::UnicodeUTF8));
        } // retranslateUi
    
    };
    
    namespace Ui {
        class Sudoku: public Ui_sudoku {};
    } // namespace Ui
    
    QT_END_NAMESPACE
    
    #endif // UI_SUDOKU_H
    


  • Was auch immer du da tust, es ist wirr. Laut deinem Code definierst du in fehler.h und in sudoku.h jeweils eine Klasse Sudoku. Diese Header werden in sudoku.cpp eingebunden. Trotzdem soll nur der Fehler zu Ui::Sudoku gemeldet werden. Das halte ich für sehr unwahrscheinlich ...



  • Jungs, tut mir leid eure Geduld strapaziert zu haben! Es geht!
    Danke


Anmelden zum Antworten