1

I don't understand why this fails to compile:

#include <SomeType.h> // has a namespace called SomeNamespace

class MyApplication;

int main(...)
{
...
MyApplication application;
...
}

class MyApplication : public SomeNamespace::SomeType {
...
};

As it stands I'm getting this error from g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3

../fix-protocol/main.cpp:44: error: aggregate ‘MyApplication application’ has incomplete type and cannot be defined
Mohamed Bana
  • 1,251
  • 2
  • 17
  • 27

5 Answers5

4

In main you're instantiating an object of type MyApplication, which is still an incomplete type; you can't do that, since the compiler doesn't know anything about it yet (it would need to know e.g. how big is it, if it has any constructor, ...).

To solve your problem, you have to define MyApplication before instantiating objects of that type. Usually you place the class definition in a separate header with its name, that will be #included in any file that needs it.

Forward declarations, instead, in general are used to break cyclic dependencies and other scenarios of that kind; all they say is "there's a class named like that", but they create an incomplete type, so they can be used only to declare variables of their type, not to define them.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
3

class must be fully defined before an object is instantiated. MyApplication application;, you are trying to instantiate an object application but the compiler isn't aware of what constitutes of MyApplication since it is forward-declared. So, place the definition before main() and remove the forward declaration.

class MyApplication : public SomeNamespace::SomeType {
    ...
};

int main()
{
    MyApplication application;
}
Mahesh
  • 34,573
  • 20
  • 89
  • 115
3

You need to place the definition of MyApplication before any instantiations. In the above code, the compiler doesn't know how much stack space to allocate for the application variable, because it hasn't seen the definition of MyApplication yet.

Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
1

The problem is that C++'s compiler is one-pass, meaning that at any point in the program it needs to be able to operate without looking at the rest of the file. In your case, the problem is that in your main function, when you write

MyApplication application;

The compiler has so far only seen a forward declaration for the class (the class MyApplication; line up above). Although you do provide a definition for the class later on, the compiler hasn't seen it yet, and so it thinks you're trying to instantiate a class you have not yet defined.

To fix this, either move the definition of MyApplication up in the file above main, or move main later in the file after the definition of MyApplication.

By the way, this has nothing to do with inheritance - it's just an issue of where the class is defined.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • @Fred Nurk- The **compiler** is one-pass, but the **linker** isn't. The above code compiles because the definition of `f()` is visible in `main`, and so the compiler can type-check the code, with the linker pulling in the references later. In the case of the class, the C++ spec says that all member functions defined inline should be treated as though they were defined right after the body of the class. When this happens, the name lookup will find the member function `f()` before the global `f()`, hence the output. – templatetypedef Feb 19 '11 at 00:49
  • Look at A::g more closely: if the compiler was one-pass and it were true that "at any point in the program it needs to be able to operate without looking at the rest of the file", then A::g would call the global f rather than A::f. You mischaracterize how the standard defines this. – Fred Nurk Feb 19 '11 at 00:51
  • @Fred Nurk- Ah, I see. I should probably have said that the compiler is **mostly** one-pass, with a few minor exceptions, as in the case of member functions defined inline, which are treated as though they're defined after the class body. There's similar logic for templates, IIRC. – templatetypedef Feb 19 '11 at 00:51
  • I apologize for throwing in the red herring of the global f being inline (but the definition is not visible in main, only a declaration), but it was spur of the moment. – Fred Nurk Feb 19 '11 at 00:55
0

I think your missing the point of forward declaration of types. This answer explains it very well, and using a not-yet-declared-only-forward-declared type as base class is not possible.

Community
  • 1
  • 1
José Tomás Tocino
  • 9,873
  • 5
  • 44
  • 78