C++ &引用;字段的类型不完整“;错误

C++ &引用;字段的类型不完整“;错误,c++,C++,我的头文件中有一个错误: field "ui" has incomplete type. 我曾尝试将ui制作为指针,但没有效果。我认为我不需要这样做,因为我已经在命名空间Ui中定义了我的MainWindowClass。这是我的主窗口。h: #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QtGui/QMainWindow> #include "ui_mainwindow.h" namespace Ui { clas

我的头文件中有一个错误:

field "ui" has incomplete type.
我曾尝试将
ui
制作为指针,但没有效果。我认为我不需要这样做,因为我已经在命名空间
Ui
中定义了我的
MainWindowClass
。这是我的
主窗口。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
\ifndef主窗口
#定义主窗口
#包括
#包括“ui_main window.h”
名称空间用户界面{
类MainWindowClass;
}
类主窗口:公共QMainWindow
{
Q_对象
公众:
主窗口(QWidget*父窗口=0,Qt::WFlags标志=0);
~main窗口();
公众时段:
void slideValue(int);
私人:
Ui::MainWindowClass Ui;//错误行
};
#endif//main窗口

问题是您的
ui
属性使用了一个of类
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;
};
也会起作用


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

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

谢谢这是我仅有的头文件。我已经在上面的#includes之后声明了MainWindowClass类。我应该创建一个新的头文件吗?没有正向声明,问题是声明了一个与当前定义的类型相同的成员变量。不过,我在大括号中迷路了,没有看到这实际上是在
MainWindowClass
Ui::MainWindowClass
(成员变量)是在
MainWindow
中定义的。实际上不是同一种类型。但是,我不认为,如果使用正向声明,则变量必须是指向正向声明类型的指针或引用。否则,如果这是不可接受的,则需要包含包含类型声明的标头。而且,这是完全不可接受的ed to QtCreatorI只想补充一点,即您可以通过模板实现相同的目标。第一个示例(rextest.com/TLPEJW28982)将A声明为全局类,并在类模板定义之后对其进行定义。作为一个优势,您不必担心在何处定义结构A并避免耦合。第二个示例(RexTrace.COM/PJCD69132)将A视为嵌套结构。编译和运行的原因是由于在实例化模板时发生的两次查找。更详细的,请参阅C++模板:完整的指南,103.1两阶段查找。