87

ヘッダー ファイルに次のエラーがあります。

field "ui" has incomplete type.

ポインターを作成しようとしuiましたが、うまくいきません。MainWindowClass名前空間でmy を既に定義しているため、それを行う必要はないと思います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
4

2 に答える 2

117

type の前方宣言を使用してい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();
}
于 2012-09-17T19:54:31.563 に答える
23

問題は、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、宣言する必要があります。別のヘッダー ファイルで実行できます (通常、クラスごとに 1 つのヘッダー ファイルがあります)。
ただし、コードを次のように変更するだけです。

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;
};

も機能します。

2 つの宣言の違いに注意してください。1 つ目は前方宣言を使用し、2 つ目は実際にクラスを宣言します (ここではプロパティもメソッドもありません)。

于 2012-09-17T19:44:32.843 に答える