嵌套名称说明符中使用的不完整类型

Incomplete type used in nested name specifier

我编译了下面的代码,得到 错误:嵌套名称说明符

中使用了不完整类型“AB::B”
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
      }
   };
};

我想我在这两个 类 之间得到了循环依赖。是导致错误的原因吗? 我怎样才能绕过循环依赖?

非常感谢

就这点

class B;  //declareation

//...       

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

编译器不知道class B 是否有成员b2,因为class B 还没有定义。所以编译器会报错,因为它不知道表达式 b2() 的含义。

还有这个说法

myException():std::exception

包含语法错误。我想你的意思是

myException():std::exception()

你必须在定义class B.

之后定义构造函数

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

不在class他们之间;但是每个都有依赖于另一个的成员函数class,所以正如所写的那样存在循环依赖。

Is it the reason that cause the error?

是的。每个成员函数定义都必须在它使用的 class 之后;如果它们在 class.

中定义,这是不可能的

How can I get arround the circular dependency?

将至少一个成员函数的定义从其 class 中移出,移至另一个 class 已定义的位置。如果这些在 header 中,旨在从多个源文件中包含,则将定义移动到源文件,或者稍后在 header 中使用 inline 说明符。

例如,您可以移动 myexception 的构造函数,只在 class 中留下一个声明:

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

并在定义 B 之后内联定义它,或者在包含此 header:

的源文件中定义它
inline                     // if defined in a header
myException::myException() // no need to explicitly initialise std::exception
{
    B::b2();  // OK: B is complete now
}

首先,

class B;  //declareation       

namespace A
{

声明 B 是全局命名空间中的 class,而不是命名空间 A 中的 class。因此,使用

 B::b2();

稍后在代码中期望 b2 成为全局 B 的成员。我想你是想在命名空间 A 中转发声明 B。为此,您需要使用:

namespace A
{
   class B;  //declareation       

要删除 class 定义和成员函数实现之间的循环依赖,请在定义 classes 之后移动成员函数实现。然后,您根本不需要 B 的前向声明。有了就不疼了,但没必要。

namespace A
{
   // Optional.
   class B;

   // Class definitions without the member function implementations

   class myException(): public std::exception
   { 
      public:
         myException();
   };

   class B()
   {  
      public:
         static void b1();
         static void b2();
   };

   // Class member function implementations

   inline myException::myException(): std::exception()
   {
      B::b2();
   }

   inline void B::b1()
   {
      throw myException();
   }

   inline void B::b2()
   {
      //code
   }
}