I have 2 classes in 2 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
On the constructor lines I get the errors:
error C4430: missing type specifier - int assumed.
error C2143: syntax error : missing ',' before '&'
But when i add the classes declarations
class SparseMatrix;
in the RegMatrix.h file and
class RegMatrix;
in the SparseMatrix.h file it works fine. My question is why is it needed if i have the includes? 10x.
You can't have circular #includes (one file #includes another which #includes the first file). Forward declaring one of the classes instead of the #include will break the chain and allow it to work. Declaring the class name allows you to use the name without having to know about the internal bits of the class.
BTW, the desire for circular #includes is a design smell. Perhaps you could create an interface that the two classes can depend on instead? Then they won't have to mutually depend on each other.
Your header inclusion won't work, see what would happen if i include SparseMatrix.h after resolving includes:
#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
So basically, SparseMatrix is undefined. You can't do anything about it. Just declare your class forward declaration.
Statements like
class SparseMatrix;
are called forward declarations. It tells the compiler that "somehere" there is a class of that name. It makes the compiler happy and works perfectly as long as the forward declaring file uses either a pointer or a reference to the forward referenced class. Thats because, from compiler point of view, pointers or references are just 4 bytes irrespective of the class contents.
In OP's code, both SparseMatrix
and RegMatrix
are used only as (const) references, so forward declaration is sufficient to make it work.
However, if the forward declaring file does something which requires the compiler to know its size, e.g.
void foo( SparseMatrix ); // note pass by value
then the compiler would complain :-)
In the particular situation posed by OP, my preference is to abandon the mutual #include
altogether and design the interface just based on forward declarations. The implementation (i.e. .cpp files) may have to include both header files, but that is not a problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With