내 헤더 파일에 오류가 있습니다.
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
답변
유형에 대해 앞으로 선언을 사용하고 있습니다 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();
}
답변
문제는 ui
속성 이 class 의 정방향 선언 을 사용 Ui::MainWindowClass
하므로 “불완전한 유형”오류가 발생한다는 것입니다.
이 클래스가 선언 된 헤더 파일을 포함하면 문제가 해결됩니다.
편집하다
귀하의 의견에 따라 다음 코드 :
namespace Ui
{
class MainWindowClass;
}
클래스를 선언 하지 않습니다 . 이는 링크 타임에 클래스가 어느 시점에 존재할 것임을 의미 하는 포워드 선언 입니다.
기본적으로 컴파일러에게 유형이 존재할 것이며 이에 대해 경고해서는 안된다고 알려줍니다.
그러나 클래스 는 어딘가에 정의되어야 합니다.
이러한 유형에 대한 포인터 가있는 경우에만 작동합니다 .
불완전한 유형의 정적으로 할당 된 인스턴스를 가질 수 없습니다.
따라서 실제로 불완전한 유형을 원하고 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's 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;
};
또한 작동합니다.
두 선언의 차이점에 유의하십시오. 첫 번째는 정방향 선언을 사용하고 두 번째는 실제로 클래스를 선언합니다 (여기서는 속성이나 메서드가 없음).