I have two classes both defined in separate header files. Each file has a field that is type of other class. Now I included in header of each file the header of other file, but compiler is generating errors. What am i missing?
6 Answers
You cannot have each class have "a field that is type of other class"; that would be a recursive definition and not only the compiler would not be able to make any sense out of it, it does not even make logical sense.
Each class having a field that is type of the other class is the kind of impossibility that you only see in M.C. Escher drawings, or animations thereof, like this one:
B. de Smit and H. W. Lenstra - Source: escherdroste.math.leidenuniv.nl
based on Escher's "Print Gallery" Lithograph, 1956, see Wikipedia
One of the two fields will have to be a pointer, so as to break the recursive containment, and avoid the logical impossibility.
Which brings us to the next problem: if class B is to contain an instance of class A, then obviously, A has to be declared before class B, so that A is already known to the compiler when compiling B. But if class A is declared before class B, how can we declare a pointer to B in A? Class B is not known yet at the time that A is compiled! The answer to this is a special construct known as forward declaration which exists precisely in order to accommodate situations like this. A forward declaration of class B looks like this:
class B;
All it is telling the compiler is that there will be a class called B. It does not tell the compiler anything about the contents of class B, so there is very little we can do with it, but we can do one thing: declare pointers to B.
So, the full solution to the problem looks like this:
file "A.h":
/* This is called a "forward declaration". We use it to tell the compiler that
the identifier "B" will from now on stand for a class, and this class will be
defined later. We will not be able to make any use of "B" before it has been
defined, but we will at least be able to declare pointers to it. */
class B;
class A
{
/* We cannot have a field of type "B" here, because it has not yet been
defined. However, with the forward declaration we have told the compiler
that "B" is a class, so we can at least have a field which is a pointer
to "B". */
B* pb;
}
file "B.h":
#include "A.h"
class B
{
/* the compiler now knows the size of "A", so we can have a field
of type "A". */
A a;
}

- 56,297
- 11
- 110
- 142
-
2[Animation source](http://escherdroste.math.leidenuniv.nl/index.php?menu=animation) – Potatoswatter May 16 '17 at 00:20
-
@Potatoswatter thanks a lot! I amended the caption of the image. – Mike Nakis May 16 '17 at 00:33
-
1The image is perfect here ! – OrenIshShalom Dec 30 '21 at 04:29
-
1Regarding the »[…] it does not even make logical sense.« I would like to point out [mutually recursive datatypes](https://en.wikipedia.org/wiki/Recursive_data_type#Mutually_recursive_data_types), which are no problem in other programming languages (like haskell) and therefore have a logical meaning. – user3389669 Mar 03 '22 at 07:51
-
@user3389669 thanks, this is interesting. Recursive definitions are common in compiler grammars. But a recursive definition is one thing, and recursive ***containment*** is another. A definition (recursive or not) in a grammar serves to describe how to parse input and generate a production. In the general case, the recursive definition has an end clause, so given finite input you get a finite production. There certainly is no logical impossibility there. – Mike Nakis Mar 03 '22 at 09:36
You shouldn't include the header files inside the other ones, just include the header files in your source files.
In the headers you can use a forward declaration:
// In Class1.h
class Class2;
// In class2.h
class Class1;
Also you can protect against a file being included twice using the preprocessor:
// Class1.h
#ifndef __CLASS_1_H
#define __CLASS_1_H
// content
#endif

- 8,227
- 35
- 58
-
7NOTE: forward declarations mean that you can only use that class as a pointer in the header file. Not a class instance. – Gregor Brandt Dec 15 '11 at 21:32
-
1You can also use it as a return type or parameter type in the declaration of functions and as part of a reference type. – CB Bailey Dec 15 '11 at 21:44
-
You shouldn't use reserved names for include guards (or anything else for that matter), or you might run into problems like [this](http://stackoverflow.com/questions/3345159). – Mike Seymour Dec 16 '11 at 00:48
-
@GregorBrandt so if l can't use it as an instance then is useless all the stuff here – vincent thorpe May 16 '19 at 20:51
I know this is an old topic but maybe you are still interested in solution!
Actually in C++ you can use two classes recursively without using pointers and here is how to do it.
file: a.h
#include <b.h>
class A {
B<> b;
}
file: b.h
class A;
template<typename T = A>
class B {
T a;
}
file: main.cpp
#include "a.h"
A a;
and that's all!
of course this is just for curiosity :)

- 5,958
- 2
- 21
- 29
-
3Have you tried to compile it? MSVC gives me the error: `"B::a" uses an undefined class "A"` – kinokijuf Jan 17 '16 at 13:13
-
1BTW, this not meant to be used in production codes. This just for fun and that's why not marked as answer. – Boynux Jan 18 '16 at 01:27
You probably want to use forward declaration, unless you actually want to put instance of each class in each other. In which case you shouldn't use anything.

- 138,757
- 24
- 193
- 173
If B can only exist within A, I seem to be able to create A and B without using a pointer. B has to simply forward declare A and not include it (avoiding the recursive inclusion).
In my case, a Document
has a Section
which gets a reference to its Document
.
section.h
class Document;
class Section
{
public:
Section(Document& document) : document{document} {}
private:
Document& document;
};
document.h
#include "section.h"
class Document
{
public:
Document() : section{*this} {}
private:
Section section;
};
main.cpp
#include "document.h"
int main()
{
Document document{};
}
This code compiles with g++
and runs on Linux.
A (complex) set of ifdef
might enable it for other cases, but I'm not sure about the readability...

- 792
- 8
- 16
-
1A reference is implemented as a pointer, so essentially you are doing the same thing as a pointer. – johnbakers Aug 27 '19 at 21:56
Besides the possibility of forward declaration - if it seems that you need two classes mutually within the other it is out of my experience a sign for a mistake in the depth of inheritance. Eather the classes are a kind of siblings and you should create a parent class for both. Or you are trying to use a class that is in fact a parent class within one that should have a sibling from this parent class. Then you should create this sibling as a third class.

- 11
- 4