C ++嵌套类/转发声明问题

时间:2010-04-08 13:52:31

标签: c++ forward-declaration nested-class

是否可以转发声明嵌套类,然后将其用作外部类的具体(不是指向/引用)数据成员的类型?

class Outer;

class Outer::MaybeThisWay   // Error: Outer is undefined
{
};

class Outer
{
 MaybeThisWay x;

 class MaybeThatOtherWay;

 MaybeThatOtherWay y;   // Error: MaybeThatOtherWay is undefined
};

6 个答案:

答案 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__InnerOuter_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());
    }
};