是否可以转发声明嵌套类,然后将其用作外部类的具体(不是指向/引用)数据成员的类型?
即
class Outer;
class Outer::MaybeThisWay // Error: Outer is undefined
{
};
class Outer
{
MaybeThisWay x;
class MaybeThatOtherWay;
MaybeThatOtherWay y; // Error: MaybeThatOtherWay is undefined
};
答案 0 :(得分:37)
你不能像这样向前声明一个嵌套类。
根据您尝试做的事情,也许您可以在外层使用命名空间而不是类。你可以向前声明这样一个类没问题:
namespace Outer {
struct Inner;
};
Outer::Inner* sweets; // Outer::Inner is incomplete so
// I can only make a pointer to it
如果你的Outer绝对必须是一个类,并且你不能将它变成一个命名空间,那么你需要在你转发声明Inner的上下文中使用Outer作为一个完整的类型。
class Outer
{
class Inner; // Inner forward-declared
}; // Outer is fully-defined now
Outer yes; // Outer is complete, you can make instances of it
Outer::Inner* fun; // Inner is incomplete, you can only make
// pointers/references to it
class Outer::Inner
{
}; // now Inner is fully-defined too
Outer::Inner win; // Now I can make instances of Inner too
答案 1 :(得分:15)
如果没有完全指定包含类,则无法转发声明嵌套类。这个小技巧有点解决了这个问题
class Outer_Inner
{
};
class Outer
{
public:
typedef Outer_Inner Inner;
};
这对我有用,因为我的命名约定Outer_Inner
不是有效的类名,所以很明显它引用了一个嵌套类。
您仍然无法转发声明嵌套类,如下所示:
class Outer::Inner;
但至少它可以通过以下方式声明:
class Outer_Inner;
如果您不喜欢Outer_Inner看起来的方式,您可以采用更适合您口味的嵌套类的命名约定。 Outer__Inner
,Outer_nested_Inner
等
答案 2 :(得分:1)
不,但
出了什么问题class Outer {
public: //or protected or private
class Inner {
};
private:
Inner foo;
};
前方声明在这里没有意义,除非我遗漏了某些东西(由于你的问题在很多细节上都缺乏,所以可以看到)
请记住,如果一个类是前向声明的,那么你只能声明对前向声明类型的对象的引用或指针。你不能对它做任何其他事情,包括访问它的成员或功能。
答案 3 :(得分:1)
如果一个类已被前向声明(但你还没有完整的定义)那么你只能声明一个指针,因为编译器还不知道类的大小(也没有名字)其领域或方法)。
答案 4 :(得分:0)
如果声明类型为MaybeThatOtherWay
的属性,而不是引用或指针,则编译器必须知道类的完整定义以确定外部类的大小。因此,您不能使用前向声明和那种字段声明,无论它是否是嵌套类。
答案 5 :(得分:0)
如果您只需要一个类型作为函数参数或静态变量,它可以在客户端完成。例如,要从外部接收事件通知:
class Client {
public:
private:
static void gotIt(int event);
class Helper;
};
#include <outer.hpp>
class Client::Helper {
public:
static void fromOuter(Outer::Inner const& inner)
{
gotIt(inner.event());
}
};