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

Incomplete type used in nested name specifier

本文关键字:类型 说明符 嵌套      更新时间:2023-10-16

我编译了以下代码,得到错误:嵌套名称说明符中使用了不完整的类型"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
      }
   };
};

我认为这两个类之间存在循环依赖关系。这是导致错误的原因吗?如何获得循环依赖关系?

非常感谢

我认为这两个类之间存在循环依赖关系。

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

这是导致错误的原因吗?

是的。每个成员函数定义都必须在它使用的类之后;如果它们是在类中定义的,这是不可能的。

如何获得循环依赖关系?

将至少一个成员函数的定义移出其类,移动到定义另一个类的点。如果它们在一个标头中,打算从多个源文件中包含,则将定义移动到源文件,或者稍后在标头中使用inline说明符。

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

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

并在内联、B定义之后或在包含此标头的源文件中定义它:

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是全局命名空间中的类,而不是命名空间A中的类。因此,的使用

 B::b2();

代码稍后期望CCD_ 6是全局CCD_。我认为您的意思是在名称空间A中转发声明B。为此,您需要使用:

namespace A
{
   class B;  //declareation       

要删除类定义和成员函数实现之间的循环依赖关系,请在定义类之后移动成员函数实现。那么,您根本不需要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
   }
}

此时

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

编译器不知道类B是否具有成员b2,因为类B还没有被定义。因此编译器会发出一个错误,因为它不知道表达式b2()的含义。

还有这句话

myException():std::exception

包含语法错误。我想你是指

myException():std::exception()

您必须在定义类B之后定义构造函数。