Missing type error in constructor declaration

I have 2 classes in two different files:

RegMatrix.h:

#ifndef _RM_H #define _RM_H #include "SparseMatrix.h" ... class RegMatrix{ ... RegMatrix(const SparseMatrix &s){...} //ctor ... }; #endif 

SparseMatrix.h:

 #ifndef _SM_H #define _SM_H #include "RegMatrix.h" ... class SparseMatrix{ ... SparseMatrix(const RegMatrix &r){...} //ctor ... }; #endif 

In the constructor lines, I get errors:

error C4430: missing type specifier - int is assumed.

error C2143: syntax error: missing ',' before '&'

But when I add class declarations

 class SparseMatrix; 

in the RegMatrix.h file and

 class RegMatrix; 

in the SparseMatrix.h file, it works fine. My question is, why is this necessary if I have included? 10x

+4
source share
4 answers

You cannot have round #includes (one file # includes another, which # includes the first file). Forward, declaring one of the classes instead of #include, it will break the chain and allow it to work. Declaring a class name allows you to use the name without having to know about the internal bits of the class.

By the way, the desire for circular #includes is the smell of design. Perhaps you could create an interface that both classes can depend on? Then they will not have to depend on each other.

+9
source

Including the header will not work, see what happens if I enable SparseMatrix.h after permission:

 #ifndef _SM_H #define _SM_H /// start of #include "RegMatrix.h" #ifndef _RM_H #define _RM_H /// start of #include "SparseMatrix.h" inside "RegMatrix.h" #ifndef _SM_H // skipping, because _SM_H is defined and the condition is false #endif /// end of #include "SparseMatrix.h" inside "RegMatrix.h" class RegMatrix{ ... RegMatrix(const SparseMatrix &s){...} //ctor ... }; #endif /// end of #include "RegMatrix.h" ... class SparseMatrix{ ... SparseMatrix(const RegMatrix &r){...} //ctor ... }; #endif 

Basically, SparseMatrix is ​​undefined. There is nothing you can do about it. Just declare your class declaration ahead.

+5
source

If you enable RegMatrix.h first, it will include SparseMatrix.h . This will then return to enabling RegMatrix.h and skip because the header protection is defined. Then SparseMatrix continues to be defined, except RegMatrix has never been announced. You will then receive an error message.

You cannot turn on the circular. You must post an ad to one or both of them, just like you.

+3
source

Statements like

 class SparseMatrix; 

called forward ads. It tells the compiler that “somewhere” is a class of this name. This makes the compiler happy and works fine, as long as the declaration file in the forward direction uses either a pointer or a class reference with a direct link. This is because, from the point of view of the compiler, pointers or references are only 4 bytes, regardless of the contents of the class.

In the OP-code, both SparseMatrix and RegMatrix are used only as (const) links, therefore, a forward declaration is sufficient to declare this announcement.

However, if the direct declaration file does something that requires the compiler to know its size, for example.

 void foo( SparseMatrix ); // note pass by value 

then the compiler will complain :-)

In the specific situation specified by the OP, I prefer to abandon the mutual #include altogether and design an interface based only on forward declarations. An implementation (e.g. .cpp files) may include both header files, but this is not a problem.

+2
source

All Articles