Incomplete Type

What's up guys. I've been stuck at this roadblock for a few weeks now and it's really not good for my sanity. I haven't posted about it before due to the somewhat extensive amount of code I'd have to post, but I'm at my wit's end.

The compiler is getting mad at me for trying to work with an incomplete type. The code is structured like:
cCommand class is for the actual commands along with their handles.
cCmdScript class is the base class that new command scripts will be derived from.
cCmdLoader class is a class that I can instantiate like cCmdLoader accessor; and have it default construct a pointer to all of the present scripts (derived from cCmdScript class).

"command.h"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef COMMAND_H
#define COMMAND_H
#include <iostream>
class cCommand{
public:
	std::string m_name;
	bool m_haschild;
	void* _HandleCmd;
	cCommand* m_childcmd;
};
class cCmdScript{
	std::string m_name;
public:
	cCmdScript();
	cCmdScript(std::string name);
	virtual cCommand* GetCommandTable();
};
class cCmdLoader{
	cCmdScript* m_pointer;
	static const int m_scriptNum=1;   //number of command scripts present
public:
	cCmdLoader();
	static int GetScriptNum();
};
#endif 


"command.cpp"
1
2
3
4
5
6
7
8
9
10
11
12
#include "stdafx.h"
#include <iostream>
#include "command.h"
#include "loadscript.h"

cCmdScript::cCmdScript(){}
cCmdScript::cCmdScript(std::string name):m_name(name){}
cCommand* cCmdScript::GetCommandTable(){return NULL;}
cCmdLoader::cCmdLoader(){
	m_pointer=print_command::AddCmd();
}
int cCmdLoader::GetScriptNum(){return m_scriptNum;}


"loadscript.h"
1
2
3
4
5
6
7
#ifndef LOADSCRIPT_H
#define LOADSCRIPT_H
#include "command.h"

///***forward declare all command scripts here***///
class print_command;
#endif 


"sc_print.cpp"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "stdafx.h"
#include "loadscript.h"
class print_command:public cCmdScript{
public:
	print_command():cCmdScript("print_command"){}
	cCommand* GetCommandTable(){
		static cCommand printtable[]=
		{
			{"triangle",false,_HandlePrintTriangle,NULL},
			{"tri",false,_HandlePrintTriangle,NULL},
			{"rectangle",false,_HandlePrintRectangle,NULL},
			{"rec",false,_HandlePrintRectangle,NULL},
			{"square",false,_HandlePrintSquare,NULL},
			{"squ",false,_HandlePrintSquare,NULL},
			{"all",false,_HandlePrintAll,NULL},
		};
		static cCommand commandtable[]=
		{
			{"print",true,NULL,printtable}
		};
		return commandtable;
	}
	static void _HandlePrintTriangle(){
		return;
	}
	
	static void _HandlePrintRectangle(){
		return;
	}

	static void _HandlePrintSquare(){
		return;
	}

	static void _HandlePrintAll(){
		return;
	}
	static print_command* AddCmd(){
		return new print_command;
	}
};


The problem appears in command.cpp in the cCmdLoader constructor. As much as I'd like it to, the compiler isn't recognizing the print_command class at the time the compiler gets to command.cpp. I've moved the code around in just about every way I can think of but to no avail. The reason why I have the print_command (and every new command to be added) in its own .cpp file is so that editing and adding new commands as my program expands is easier.
Thanks guys; I know it was a long read. I appreciate it.
Last edited on
The problem is that, because the cCmdLoader constructor is calling a method of print_command, it needs to be able to see the print_command definition. There's no way around it. This is why we put class definitions in headers - so that other translation units that need to know the definition of a class can see that definition by including the header file.

Separating out your classes into different files is a perfectly sensible thing to do, but you still need those class definitions to be in headers. I'd advise making a print_command.h file, and putting the class definition there.

You don't need to include the method definitions in the header. In fact, I'd advise against it. Just put the method declarations inside the class definition, and then leave the method definitions in the .cpp file.

Edit: In other words, do it like you've done for command.h and command.cpp.
Last edited on
Topic archived. No new replies allowed.