C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 39:
[39.13] What special considerations are needed when forward declarations are used with inline functions?

The order of class declarations is critical.

The compiler will give you a compile-time error if the first class contains an inline function that invokes a member function of the second class. For example,

class Fred;  // Okay: forward declaration

class Barney {
public:
  void method()
  {
    x->yabbaDabbaDo();  // Error: Fred used before it was defined
  }
private:
  Fred* x;  // Okay: the first can point to an object of the second
};

class Fred {
public:
  void yabbaDabbaDo();
private:
  Barney* y;
};
There are a number of ways to work around this problem. One workaround would be to define Barney::method() with the keyword inline below the definition of class Fred (though still within the header file). Another would be to define Barney::method() without the keyword inline in file Barney.cpp. A third would be to use nested classes. A fourth would be to reverse the order of the classes so the "used" class is defined before the class that uses it:
class Barney;  // Okay: forward declaration

class Fred {
public:
  void yabbaDabbaDo();
private:
  Barney* y;  // Okay: the first can point to an object of the second
};

class Barney {
public:
  void method()
  {
    x->yabbaDabbaDo();  // Okay: Fred is fully defined at this point
  }
private:
  Fred* x;
};
Just remember this: Whenever you use forward declaration, you can use only that symbol; you may not do anything that requires knowledge of the forward-declared class. Specifically you may not access any members of the second class.