3

I have defined the two following classes in two different files:

#include "B.h"
class A {
 public:
  A() {}
  ~A() {}
  f() {
   auto b = new B(this);
  }
};

And in another file:

#include "A.h"
class B {
 public:
  B(A* a) {}
  ~B() {}
}

But I don't understand the compile error I get:

B.h: error: ‘A’ has not been declared
A.cpp: error: no matching function for call to ‘B(A&)‘
                                                      *this);
              note: candidate is:
              note: B(int*)
              note: no known conversion for argument 1 from ‘A’ to ‘int*’

Why is my A class has been converted to int ?!

klaus
  • 754
  • 8
  • 28

2 Answers2

6

This is a ciucular dependency issue. B.h includes A.h, and A.h includes B.h.

In fact, you don't need the #include "A.h" in B.h, A doesn't need to be complete type here (i.e. use it as the parameter type in the function declaration), forward declaration is sufficient.

class A;  // forward declaration

class B {
 public:
  B(A* a) {}
  ~B() {}
};
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
3

You have a circular dependency here. The definition of class A can't depend on the definition of class B, if the latter depends on the definition of the former. You can get around this by transforming one of the #include directives into a forward declaration. In your case,

// Don't include the complete definition
// #include "A.h"

class A; // Instead: forward-declare A

class B {
  public:
   B(A* a) {}
  ~B() {}
};

You probably need the definition of A in your implementation file nevertheless. But this is fine, you can #include "A.h" in a translation unit without falling back to the circular dependency issue.

lubgr
  • 37,368
  • 3
  • 66
  • 117