C++ Circular Dependency

Example
Imagine a spaceship with a weapon, where the weapon is a separate class, and the weapon must know its owner: class Ship { Weapon &weapon; }; class Weapon { Ship &owner; }; This does not work, as the Weapon class is undefined when defining class Ship. The remedy is a forward declaration: class Weapon; // forward definition class Ship { ...

Discussion
The above approach can get very tricky in larger class hierarchies. Imagine the example split into files, : class Weapon;                      // forward declaration class Ship { public: Ship : weapon(0) {} void fire { weapon->fire; } // Error: we are *not* allowed to use // methods of the undefined class. Weapon *weapon;                // We may have a pointer to an undefined };                                 // class, but not a reference. : class Ship;                        // forward declaration class Weapon { public: Weapon(Ship &owner) : owner(owner), fired(0) {} void fire { fired++; } Ship &owner; int fired; }; and : int main(void) { Ship R9a; Weapon laser(R9a); R9a.weapon = &laser; } Note that although we would like to initialize the Ship with a Weapon reference, it is impossible to retain the initialization of the Weapon class with the Ship reference. We cannot have both. Therefore, we opt to use a weapon pointer which is set after creating both the Ship and the Weapon. If we forget to set it, the program will fail, so it should be changed to something similar to: void fire { if(weapon) weapon->fire; }
 * 1) pragma once
 * 2) include "weapon.h"
 * 1) pragma once
 * 2) include "ship.h"
 * 1) include "weapon.h"
 * 2) include "ship.h"

However, the above example doesn't even compile. The problem is that  uses   before   is defined. We may not access members of an as yet undefined class.

The solution is unsatisfying: we cannot retain  as an inline member function. We have to edit : ... class Ship { public: Ship : weapon(0) {} void fire;         // May not be inline, as it accesses // a weapon member. Weapon *weapon; }; add put the  implementation in a separate translation unit (  file): void Ship::fire { weapon->fire; }
 * 1) include "ship.h"

Conclusion

 * Try to avoid circular dependencies in your design, as the C++ implementation may get hairy.
 * Use forward declarations to allow circular dependencies if deemed necessary.
 * As we cannot assume anything about a forward declared class, we cannot access its members in inline functions. Move function definitions accessing forward declared class members to a separate translation unit ( file).