In meiner Header-Datei ist ein Fehler aufgetreten:
field "ui" has incomplete type.
Ich habe versucht, ui
einen Zeiger zu erstellen, aber das funktioniert nicht. Ich glaube nicht, dass ich das tun muss, weil ich meine bereits MainWindowClass
im Namespace definiert habe Ui
. Das ist mein mainwindow.h
:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui/QMainWindow>
#include "ui_mainwindow.h"
namespace Ui {
class MainWindowClass;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0, Qt::WFlags flags=0);
~MainWindow();
public slots:
void slideValue(int);
private:
Ui::MainWindowClass ui; //error line
};
#endif // MAINWINDOW_H
Antworten:
Sie verwenden eine Forward-Deklaration für den Typ
MainWindowClass
. Das ist in Ordnung, bedeutet aber auch, dass Sie nur einen Zeiger oder Verweis auf diesen Typ deklarieren können. Andernfalls hat der Compiler keine Ahnung, wie das übergeordnete Objekt zugewiesen werden soll, da er die Größe des vorwärts deklarierten Typs nicht kennt (oder ob er tatsächlich einen parameterlosen Konstruktor usw. hat).Also wollen Sie entweder:
// forward declaration, details unknown class A; class B { A *a; // pointer to A, ok };
Oder wenn Sie keinen Zeiger oder keine Referenz verwenden können ...
// declaration of A #include "A.h" class B { A a; // ok, declaration of A is known };
Irgendwann muss der Compiler die Details von kennen
A
.Wenn Sie nur einen Zeiger auf speichern, werden
A
diese Details beim Deklarieren nicht benötigtB
. Sie werden irgendwann benötigt (wann immer Sie den Zeiger tatsächlich dereferenzierenA
), wahrscheinlich in der Implementierungsdatei, in der Sie den Header einfügen müssen, der die Deklaration der Klasse enthältA
.// B.h // header file // forward declaration, details unknown class A; class B { public: void foo(); private: A *a; // pointer to A, ok }; // B.cpp // implementation file #include "B.h" #include "A.h" // declaration of A B::foo() { // here we need to know the declaration of A a->whatever(); }
quelle
Das Problem ist, dass Ihre
ui
Eigenschaft eine Vorwärtsdeklaration der Klasse verwendetUi::MainWindowClass
, daher der Fehler "unvollständiger Typ".Das Einfügen der Header-Datei, in der diese Klasse deklariert ist, behebt das Problem.
BEARBEITEN
Basierend auf Ihrem Kommentar den folgenden Code:
namespace Ui { class MainWindowClass; }
ist nicht eine Klasse deklarieren. Es ist eine Vorwärtsdeklaration , was bedeutet, dass die Klasse irgendwann zum Zeitpunkt der Verknüpfung vorhanden sein wird.
Grundsätzlich teilt es dem Compiler nur mit, dass der Typ vorhanden sein wird und dass er nicht davor warnen sollte.
Aber die Klasse muss irgendwo definiert werden .
Beachten Sie, dass dies nur funktionieren kann, wenn Sie einen Zeiger auf einen solchen Typ haben.
Sie können keine statisch zugewiesene Instanz eines unvollständigen Typs haben.
Entweder möchten Sie tatsächlich einen unvollständigen Typ, und dann sollten Sie Ihr
ui
Mitglied als Zeiger deklarieren :namespace Ui { // Forward declaration - Class will have to exist at link time class MainWindowClass; } class MainWindow : public QMainWindow { private: // Member needs to be a pointer, as it's an incomplete type Ui::MainWindowClass * ui; };
Oder Sie möchten eine statisch zugewiesene Instanz von
Ui::MainWindowClass
, und dann muss sie deklariert werden. Sie können dies in einer anderen Header-Datei tun (normalerweise gibt es eine Header-Datei pro Klasse).Aber ändern Sie einfach den Code in:
namespace Ui { // Real class declaration - May/Should be in a specific header file class MainWindowClass {}; } class MainWindow : public QMainWindow { private: // Member can be statically allocated, as the type is complete Ui::MainWindowClass ui; };
wird auch funktionieren.
Beachten Sie den Unterschied zwischen den beiden Erklärungen. Der erste verwendet eine Vorwärtsdeklaration, während der zweite die Klasse tatsächlich deklariert (hier ohne Eigenschaften oder Methoden).
quelle
MainWindowClass
.Ui::MainWindowClass
(Mitgliedsvariable) ist definiert inMainWindow
. Nicht wirklich die gleiche Art.