It is an error because the precompiler cannot find the appropriate type declarations (assuming you are using include guards).
Assume a.h is compiled first. It includes b.h, so the text from b.h is added to the top of a.h. But in b.h, a.h is included, so the text from a.h would have to be put at the top of the b.h code. At that point, if you do not have include guards then it would continue for ever, which is bad. However, if you do have include guards, they would kick in there and not add the text from a.h above the text from b.h. At that point whatever code in b.h requires the inclusion of a.h would fail to compile.
Generally the solution is first to make sure that you don't #include files that you don't need, and use forward declarations wherever you can. For example, if you only declare a member pointer to a class, you can just forward declare the class instead of #include-ing the header that declares that class. Also, if you have inline functions that use a class, move those out of the header file.
If you use an instance of the each class in the other, you should switch one of them to use a pointer or reference instead of the actual type. You could also use the Pimpl idiom (Compiler Firewall) to move the need for the includes to the source file.