Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ circular header includes [duplicate]

I know that similar questions to this have been asked before but after doing my research I still have questions about circular header includes.

//FooA.h
#ifndef H_FOOA
#define H_FOOA

#include "foob.h"

class FooA{
   public:
      FooB *fooB;
};


//FooB.h
#ifndef H_FOOB
#define H_FOOB

class FooA;
class FooB{
   public:
      FooA *fooA;
};

Now if I have two circular dependencies this is the way that I have seen people on stackoverflow get around the problem. My only problem with this is that in my main.cpp I must include fooa.h first and then foob.h

//main.cpp the right way
#include "fooa.h"
#include "foob.h"

//main.cpp that will surely get a compile error
#include "foob.h"
#include "fooa.h"

Now my question is "Is there a way to forward declare these classes in a way that will allow me to not care about the order in which I include the header files in my main.cpp?"

like image 568
user1600812 Avatar asked Aug 15 '12 14:08

user1600812


4 Answers

Is there a way to forward declare these classes in a way that will allow me to not care about the order in which I include the header files in my main.cpp?

since you are dealing with simple pointers only, you can use a forward declaration here in both cases:

FooA.h

#ifndef H_FOOA
#define H_FOOA

// #include "foob.h" << not needed!
class FooB;       // << substitute with a forward declaration of FooB

class FooA{
   public:
      FooB *fooB;
};
#endif

FooB.h

#ifndef H_FOOB
#define H_FOOB

class FooA;
class FooB{
   public:
      FooA *fooA;
};
#endif
like image 166
justin Avatar answered Nov 16 '22 06:11

justin


You don't have to care about the order because fooa.h includes foob.h, and foob.h has the forward declaration for FooA. Everything is correct already in your code.

like image 44
Andrey Avatar answered Nov 16 '22 05:11

Andrey


As both classes simply contain a pointer, you don't need to include the other header. A forward declaration will do.

Any code that actually uses the other class will need the header, but that should be in a cpp file.

like image 27
AI0867 Avatar answered Nov 16 '22 05:11

AI0867


Use a forward declare in both header files.

Did you know you can declare it on the same line?

In "FooB.h"

class FooB{
    public:
        class FooA *fooA;
};

In "FooA.h"

class FooA {
    public:
        class FooB *fooB;
};
like image 23
Xathereal Avatar answered Nov 16 '22 06:11

Xathereal