C++ “字段类型不完整”错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12466055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:17:48  来源:igfitidea点击:

"Field has incomplete type" error

c++

提问by IsabellaW

There is an error in my header file:

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

field "ui" has incomplete type.

I have tried making uia pointer, but that doesn't work. I don't think I need to do that because I have already defined my MainWindowClassin the namespace Ui. This is my mainwindow.h:

我试过做ui一个指针,但这不起作用。我认为我不需要这样做,因为我已经MainWindowClass在 namespace 中定义了 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

回答by Ed S.

You are using a forward declaration for the type MainWindowClass. That's fine, but it also means that you can only declare a pointer or reference to that type. Otherwise the compiler has no idea how to allocate the parent object as it doesn't know the size of the forward declared type (or if it actually has a parameterless constructor, etc.)

您正在使用类型的前向声明MainWindowClass。这很好,但这也意味着您只能声明对该类型的指针或引用。否则编译器不知道如何分配父对象,因为它不知道前向声明类型的大小(或者它是否实际上具有无参数构造函数等)

So, you either want:

所以,你要么想要:

// forward declaration, details unknown
class A;

class B {
  A *a;  // pointer to A, ok
};

Or, if you can't use a pointer or reference....

或者,如果您不能使用指针或引用....

// declaration of A
#include "A.h"

class B {
  A a;  // ok, declaration of A is known
};

At some point, the compiler needs to know the details of A.

在某些时候,编译器需要知道A.

If you are only storing a pointer to Athen it doesn't need those details when you declare B. It needs them at some point (whenever you actually dereference the pointer to A), which will likely be in the implementation file, where you will need to include the header which contains the declaration of the class 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();
}

回答by Macmade

The problem is that your uiproperty uses a forward declarationof class Ui::MainWindowClass, hence the "incomplete type" error.

问题是您的ui属性使用了class 的前向声明Ui::MainWindowClass,因此会出现“不完整类型”错误。

Including the header file in which this class is declared will fix the problem.

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

EDIT

编辑

Based on your comment, the following code:

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

namespace Ui
{
    class MainWindowClass;
}

does NOTdeclare a class. It's a forward declaration, meaning that the class will exist at some point, at link time.
Basically, it just tells the compiler that the type will exist, and that it shouldn't warn about it.

确实声明一个类。这是一个前向声明,意味着该类将在链接时的某个时刻存在。
基本上,它只是告诉编译器该类型将存在,并且不应该对此发出警告。

But the class has to be defined somewhere.

但是类必须在某处定义

Note this can only work if you have a pointerto such a type.
You can't have a statically allocated instance of an incomplete type.

请注意,这仅在您有指向此类类型的指针时才有效。
您不能拥有不完整类型的静态分配实例。

So either you actually want an incomplete type, and then you should declare your uimember as a pointer:

所以要么你真的想要一个不完整的类型,然后你应该将你的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;
};

Or you want a statically allocated instance of Ui::MainWindowClass, and then it needs to be declared. You can do it in another header file (usually, there's one header file per class).
But simply changing the code to:

或者你想要一个静态分配的实例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;
};

will also work.

也会起作用。

Note the difference between the two declarations. First uses a forward declaration, while the second one actually declares the class (here with no properties nor methods).

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