Ошибка "Поле имеет неполный тип"
В моем файле заголовка есть ошибка:
field "ui" has incomplete type.
Я попытался сделать указатель ui
указателем, но это не сработает. Я не думаю, что мне нужно это сделать, потому что я уже определил свой MainWindowClass
в пространстве имен ui
. Это мой 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
Ответы
Ответ 1
Вы используете форвардное объявление для типа MainWindowClass
. Это прекрасно, но это также означает, что вы можете объявить только указатель или ссылку на этот тип. В противном случае компилятор понятия не имеет, как распределить родительский объект, поскольку он не знает размер прямого объявленного типа (или если на самом деле имеет конструктор без параметров и т.д.)
Итак, вы либо хотите:
// forward declaration, details unknown
class A;
class B {
A *a; // pointer to A, ok
};
Или, если вы не можете использовать указатель или ссылку....
// declaration of A
#include "A.h"
class B {
A a; // ok, declaration of A is known
};
В какой-то момент компилятор должен знать детали A
.
Если вы сохраняете указатель на A
, тогда он не нуждается в этих деталях при объявлении B
. Он нуждается в них в какой-то момент (всякий раз, когда вы на самом деле разыскиваете указатель на A
), который, скорее всего, будет в файле реализации, где вам нужно будет включить заголовок, который содержит объявление класса A
.
// 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();
}
Ответ 2
Проблема заключается в том, что ваше свойство ui
использует декларацию класса Ui::MainWindowClass
, следовательно, Ошибка "неполного типа".
Включение заголовочного файла, в котором объявлен этот класс, устранит проблему.
ИЗМЕНИТЬ
На основе вашего комментария, следующий код:
namespace Ui
{
class MainWindowClass;
}
делает НЕ объявлять класс. Это forward декларация, что означает, что класс будет существовать в какой-то момент, во время ссылки.
В основном, он просто сообщает компилятору, что тип будет существовать и что он не должен предупреждать об этом.
Но класс должен быть определен где-то.
Обратите внимание, что это может работать, только если у вас есть указатель .
Вы не можете иметь статически выделенный экземпляр неполного типа.
Итак, либо вы действительно хотите неполный тип, а затем вы должны объявить свой ui
-терент как указатель:
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 an incomplete type
Ui::MainWindowClass * ui;
};
Или вам нужен статически выделенный экземпляр Ui::MainWindowClass
, а затем он должен быть объявлен.
Вы можете сделать это в другом файле заголовка (как правило, есть один заголовочный файл для каждого класса).
Но просто изменив код на:
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;
};
также будет работать.
Обратите внимание на разницу между двумя объявлениями. Сначала используется форвардная декларация, а вторая фактически объявляет класс (здесь без свойств и методов).