error: incomplete type is not allowed

Hi,

I'm having a continual problem of wanting to make two classes refer to each other. I keep getting "error: incomplete type is not allowed" whenever the first reference is made to the next class. I'm using Intel C++ compiler for Mac. I'm not sure if there is a way around it or not. It doesn't seem to matter which order I put the class definitions. I've tried externs in front. I've tried generically declaring the classes beforehand. I've tried both of these methods with pointers to the classes, and then I just get the same error but that a pointer to an incomplete class is not allowed. Nothing seems to fix this. I'm not sure if there is something I need to learn about C++, if C++ is inherently flawed, or if the icpc compiler for Mac is inherently flawed. If anyone can help me with this, I'd appreciate it.

I should mention an example of when this comes up. Say for example, I have a class for a window I'm working with that manages the screen's border coordinates and mouse coordinates and classes for windows that open when a tab is clicked. If those classes need to refer to that window to get mouse coordinates, they are referencing the window class and since it manages them as members, it references them.

Thanks in advance for anyone's help,
Sean =)

Forward declarations.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// this compiles fine
class A;  // forward declare A

class B
{
public:
  A* b;  // so that it can be referenced here
};

class A
{
public:
  B* b;
};


Relevent link (see section 4):

http://cplusplus.com/forum/articles/10627/
Last edited on
So, you have something like this?
1
2
3
4
5
6
7
8
9
class A;
class B
{
    A a;
};
class A
{
    B b;
};
This is not possible but using pointers should be fine:
1
2
3
4
5
6
7
8
9
class A;
class B
{
    A *a;
};
class A
{
    B *b;
};


EDIT: too slow... the cool thing is that Disch has used my same names for the classes
Last edited on
Somehow this still isn't working. Example:
1
2
3
4
5
6
7
8
9
class CPos2;
class CMainWindow
{
  CPos2 *initialWindowPosition;
  CMainWindow()
  {
    initialWindowPosition->setXY(0.0,0.0);
  }
};


When I try to compile this, I get the errors:
CMainWindow.cpp: In constructor ‘CMainWindow::CMainWindow()’:
CMainWindow.cpp:7: error: invalid use of undefined type ‘struct CPos2’
CMainWindow.cpp:1: error: forward declaration of ‘struct CPos2’
Last edited on
Since CPos2 wasn't defined, the compiler can't know what setXY is, a solution for this could be:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class CPos2;
class CMainWindow
{
  CPos2 *initialWindowPosition;
  CMainWindow();
};

class CPos2
{
   // declare the method setXY
};

CMainWindow::CMainWindow()
{
    initialWindowPosition->setXY(0.0,0.0);
}
(You can split this in different cpp/header files)
BTW when does initialWindowPosition gets its value?
Last edited on
Yet to be determined. So far I haven't figured out how to manage header files and source files with classes and Makefiles. I'm going to try to make a header file and a source file for everything and see if that does any good. At this point, I don't know whether my header files should be any different than my source files, and if so, what should be in each. I'm completely confused as to how compilers can be so frustrating, and I have yet to find any way to make them work enough to actually plan my program accordingly.
Makefiles


Good lord. Nobody should have to write makefiles.

Get an IDE. There are several free ones. If you're on Windows, pick up a copy of Visual Studio (pretty sure there are free versiosn available). If that's no good you can try Code::Blocks (which is available on Mac/Linux as well). Dev-C++ is another option for Windows -- not sure if it's cross platform.

I can't imagine having to learn C++ and makefiles at the same time. I still don't understand makefiles and I've been coding for 10 years. XD

You'll be surprised how much easier everything is with a good IDE.

So far I haven't figured out how to manage header files and source files with classes


*points to previous article link where I outline a pretty solid method*
Yes, the reference article is very helpful. However, I'm still not clear on what should be in a header file versus a source file. Right now I'm basically having two of the exact same files except for having the #define HEADER_H type of stuff on the header file. That's particularly annoying because it means I have to modify two files every time I make any change. However, I am finally getting things to compile. Am I crazy or should someone write a compiler that does this stuff automatically with simply one version of the code anywhere? Oh, and what is an IDE?
Last edited on
Although I am able to get things to compile by doubling up my source code as header files, it gives me segmentation faults instead of working properly. Now I have no idea what to do next.
Right now I'm basically having two of the exact same files except for having the #define HEADER_H type of stuff on the header file.


Well no wonder you're getting errors.

Header files are for the "interface". Things like typedefs, constants, classes, structs, and function prototypes. This way any .cpp file can access any of those things by #including the file which declares them.

Source files are for the "implementation". Which is basically like function bodies. This way if you modify the code for X function, only one .cpp file needs to be recompiled, rather than every file which #includes the header.

Here's an example:

1
2
3
4
5
6
7
8
9
10
11
// myclass.h
#ifndef __MYCLASS_H__
#define __MYCLASS_H__

class MyClass
{
public:
  void PrintSomething();
};

#endif // __MYCLASS_H__ 

1
2
3
4
5
6
7
8
// myclass.cpp
#include <iostream>
#include "myclass.h"

void MyClass::PrintSomething()
{
  std::cout << "MyClass::PrintSomething was called\n";
}

1
2
3
4
5
6
7
8
9
// main.cpp
#include "myclass.h"

int main()
{
  MyClass obj;
  obj.PrintSomething();
  return 0;
}



Am I crazy or should someone write a compiler that does this stuff automatically with simply one version of the code anywhere?


I don't know how what you're doing is working -- but it's no wonder you're getting weird segmentation faults. You probably have some kind of weird compiler/linker confusion going on where code that shouldn't compile is because you're not compiling all necessary files or something. Any number of things could be going wrong.

You definately don't need to duplicate code though. In fact if you do -- the code shouldn't even be compiling. You should be getting linker errors.

Oh, and what is an IDE?


Get one.

IDE is short for "interactive development environment" or something like that. Basically it's a frontend for the compiling/linking process. It consists mainly of a text editor and treeview file viewer, and sort of attaches itself to a compiler and a debugger.

How it works is you add files to a "project", edit those files as you would in any other editor (although IDEs often add other nice features to make editing easier, like syntax highlighting, auto complete, etc) then press a single button to compile. No hassling with makefiles, no worrying about which files you need to compile and how to link them properly. The IDE handles all of it.

Here's a link to Code::Blocks, which is what I use on Ubuntu. There are screenshots and stuff so you can get an idea:

http://www.codeblocks.org/

If you're on windows you might want to look up Visual Studio as well.

But seriously. Get one.
Hello smcguffee,

Let me remind this link http://www.cplusplus.com/doc/tutorial/inheritance/
It could have save a lot from the start.
Dear All You Helpful People,

Thank you all very much for some extremely useful advice! I have to say that the links and the IDE suggestion have been extremely helpful. Since my last posted question, I have made great strides with your help.

One useful thing that I have learned is that only variables and function prototypes should go in header files for classes, and type class::functions(){function definitions;}'s should go in the *.cpp files. In one case, I even had to put type class::variable;'s in a *.cpp file in addition to in the header file with static variables, although they still didn't work like global variables for some reason that I'm not exploring yet.

Now I have run into a problem that I don't know is possible to fix, but maybe I am still doing something wrong. I've been trying to re-organize global variables and change them into members of one main class, so that things make more sense to me. I've succeeded in most cases now, which is miles from where I stated, thanks to all your help. One case that I haven't got around yet is when I have my main class inheriting from one of my classes that I want to have referencing the main class. Should this be impossible? I can see how it could be because of the circular logic. On the other hand, I got way farther with your help than I originally thought possible, so please let me know if there is a way to do this.

Thanks,

Sean
Last edited on
Topic archived. No new replies allowed.