Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve this header include loop?

Hi I already read similar questions about this topic, but I coudn't resolve my problem. I think I have to do a forward declaration so I tried the following.

I have three classes A, B and InterfaceA

Defintion InterfaceA

#ifndef INTERFACE_A_H
#define INTERFACE_A_H
#include "B.h"

namespace Example
{
  class B; // Forward declaration?
  class InterfaceA
  {
     Example::B test;

   };

}

#endif 

Definiton class A

#ifndef A_H
#define A_H
#include "InterfaceA.h"
namespace Example
{
  class A : public Example::InterfaceA
  {

  };
}
#endif

Defintion class B

#ifndef B_H
#define B_H
#include "A.h"

namespace Example
{
  class A; // Forward declaration?
  class B
  {
     Example::A test;
  };

}

#endif

main

#include "A.h"
#include "B.h"
int main()
{
  Example::A a;
  Example::B b;
}

I get the following error in visual studio:

'Example::B::test' uses undefined class 'Example::A'

Edit: Thank you so far, for all the help. It was very helpful. I think my problem was that I had a very poor design in my real project. I will change that.

Beside that I have now a better understanding for forward declarations :-)

like image 809
TruckerCat Avatar asked Mar 18 '23 19:03

TruckerCat


2 Answers

If you really need that class A references class B and viceversa, instead of having instances of A and B as data members, consider using pointers, e.g. something like this:

// A.h

#pragma once

#include <memory> // for std::unique_ptr

// Forward declaration (A references B using pointer)
class B;

class A 
{
...
    std::unique_ptr<B> m_pB;
};

And similarly:

// B.h

#pragma once

#include <memory> // for std::unique_ptr

// Forward declaration (B references A using pointer)
class A

class B 
{
...
    std::unique_ptr<A> m_pA;
};

PS
Not related to the core of your question, however note that I used #pragma once instead of "old style" #ifndef/#define/#endif include guards; #pragma once seems simpler and clearer to me.

like image 130
Mr.C64 Avatar answered Mar 20 '23 08:03

Mr.C64


You are creating circular dependency. Revise your design.

Do you really need an instance of class A inside B and B inside A?

like image 31
Alexus Avatar answered Mar 20 '23 09:03

Alexus