“字段类型不完整”错误

时间:2012-09-17 19:41:13

标签: c++

我的标头文件中有错误:

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

2 个答案:

答案 0 :(得分:88)

您正在使用类型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();
}

答案 1 :(得分:14)

问题是,您的ui媒体资源使用Ui::MainWindowClassnamespace Ui { class MainWindowClass; } ,因此出现“不完整类型”错误。

包含声明此类的头文件将解决问题。

修改

根据您的评论,以下代码:

ui

NOT 声明一个类。这是一个前向声明,这意味着该课程将在某个时间点,链接时存在 基本上,它只是告诉编译器类型将存在,并且它不应该警告它。

必须在某处定义

请注意,这只适用于此类型的指针 您不能拥有静态分配的不完整类型的实例。

所以要么你实际上想要一个不完整的类型,那么你应该将你的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; }; 实例,然后需要声明它。 您可以在另一个头文件中执行此操作(通常,每个类有一个头文件) 但只需将代码更改为:

{{1}}

也可以。

注意两个声明之间的区别。首先使用前向声明,而第二个实际声明类(这里没有属性或方法)。