As you have explained the situation, where the parameters are passed by value (i.e. copied), you have done the normal thing. In order to write code that uses A the compiler needs to know the precise size of B, i.e. the declaration. The headers a.h and b.h should have include guards to avoid an endless loop.

If method_x1() takes a reference or pointer to an A or B, rather than the copy you showed, then you can use forward declarations to break the header file dependency:
Qt Code:
  1. // a.h
  2. #ifndef A_H
  3. #define A_H
  4.  
  5. class B; // forward declaration only
  6. class A
  7. {
  8. public:
  9. void method_A1(const B &b);
  10. void method_A2(B *b);
  11.  
  12. };
  13. #endif
  14.  
  15.  
  16. // a.cpp
  17. #include "a.h"
  18. #include "b.h"
  19.  
  20. void A::method_A1(const B &b) {}
  21. void A::method_A2(B *b) {}
  22.  
  23.  
  24. // b.h
  25. #ifndef B_H
  26. #define B_H
  27.  
  28. class A; // forward declaration only
  29. class B
  30. {
  31. public:
  32. void method_B1(A &a);
  33. void method_B2(const A *a);
  34. };
  35. #endif
  36.  
  37. // b.cpp
  38. #include "b.h"
  39. #include "a.h"
  40.  
  41. void B::method_B1(A &a) {}
  42. void B::method_B2(const A *a) {}
To copy to clipboard, switch view to plain text mode 
The compiler then requires only a pointer to B, of known size, to build code using A. It no longer requires the full declaration of B. The full declaration of B will be required in the implementation of A.

In large libraries with lots of inter-relationships these measures can reduce compilation time quite a bit by reducing the amount of pre-processor material to be handled.