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

时间:2015-03-23 16:45:13

标签: c++ circular-dependency

我遵守了以下代码,并得到了 错误:嵌套名称说明符

中使用的不完整类型'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
      }
   };
};

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

非常感谢

3 个答案:

答案 0 :(得分:3)

  

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

不在班级之间;但每个都有依赖于另一个类的成员函数,因此写入时存在循环依赖。

  

是导致错误的原因吗?

是。每个成员函数定义必须在它使用的类之后;如果在课堂上定义它们是不可能的。

  

如何解决循环依赖?

将至少一个成员函数的定义移出其类,定义到另一个类的定义。如果它们位于标题中,旨在包含在多个源文件中,则将定义移动到源文件,或者稍后使用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
}

答案 1 :(得分:1)

首先,

class B;  //declareation       

namespace A
{

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

 B::b2();

稍后在代码中期望b2成为全局B的成员。我认为您打算在名称空间B中声明A。为此,您需要使用:

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
   }
}

答案 2 :(得分:0)

此时

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类的定义之后定义构造函数。