Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Field has incomplete type" error

Tags:

c++

There is an error in my header file:

field "ui" has incomplete type. 

I have tried making ui a pointer, but that doesn't work. I don't think I need to do that because I have already defined my MainWindowClass in the namespace Ui. This is my 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 
like image 853
IsabellaW Avatar asked Sep 17 '12 19:09

IsabellaW


People also ask

Has incomplete type error in c++?

The problem is that your ui property uses a forward declaration of class Ui::MainWindowClass , hence the "incomplete type" error. Including the header file in which this class is declared will fix the problem. does NOT declare a class.

Does struct have incomplete type?

The error means that you try and add a member to the struct of a type that isn't fully defined yet, so the compiler cannot know its size in order to determine the objects layout. In you particular case, you try and have struct Cat hold a complete object of itself as a member (the mother field).

What is incomplete type C?

The ISO C standard introduced the term “incomplete type” to formalize a fundamental, yet misunderstood, portion of C, implicit from its beginnings. This section describes incomplete types, where they are permitted, and why they are useful.


2 Answers

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.)

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.

If you are only storing a pointer to A then 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.

// 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(); } 
like image 51
Ed S. Avatar answered Oct 13 '22 06:10

Ed S.


The problem is that your ui property uses a forward declaration of class Ui::MainWindowClass, hence the "incomplete type" error.

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 NOT declare 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 pointer to 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 ui member as a pointer:

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:

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).

like image 45
Macmade Avatar answered Oct 13 '22 04:10

Macmade