Search code examples
c++circular-dependency

Incomplete type used in nested name specifier


I complied the following code, and get error: incomplete type ‘AB::B’ used in nested name specifier

class B;  //declareation       

namespace A
{
   class myException():public std::exception
   { 
      public:
         myException():std::exception()
      {
         B::b2();  //error: incomplete type ‘A::B’ used in nested name specifier
      }
   };

   class B()
   {  
      static void b1()
      {
         throw myException();
      }
      static void b2()
      {
         //code
      }
   };
};

I think I got a circular dependency between these two classes. Is it the reason that cause the error? How can I get arround the circular dependency?

Thanks a lot


Solution

  • I think I got a circular dependency between these two classes.

    Not between the classes themselves; but each has member functions that depend on the other class, so as written there is a circular dependency.

    Is it the reason that cause the error?

    Yes. Each member function definition has to come after the class that it uses; which is impossible if they are defined in the class.

    How can I get arround the circular dependency?

    Move the definition of at least one of the member functions out of its class, to a point at which the other class is defined. If these are in a header, intended to be included from multiple source files, then either move the definition to a source file, or to later on in the header with an inline specifier.

    For example, you could move the constructor of myexception, leaving just a declaration in the class:

    class myException():public std::exception
    { 
    public:
        myException();  // OK: no use of incomplete type here
    };
    

    and define it either inline, after the definition of B, or in a source file that includes this header:

    inline                     // if defined in a header
    myException::myException() // no need to explicitly initialise std::exception
    {
        B::b2();  // OK: B is complete now
    }