C++ circular header includes [duplicate]

2020-04-04 17:05发布

问题:

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?"

回答1:

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


回答2:

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.



回答3:

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.



回答4:

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;
};