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