2010-04-08 307 views
32

是否有可能前向声明一个嵌套类,然后用它作为类型的混凝土(未指针/参考)外类的数据成员?C++嵌套类/向前声明问题

I.E.

class Outer; 

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

class Outer 
{ 
MaybeThisWay x; 

class MaybeThatOtherWay; 

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

代码如下的循环链“外包含外包含外包含外......” – Muxecoid 2010-04-08 13:56:15

+0

可能的重复[如何转发声明一个内部类?](http://stackoverflow.com/questions/1021793/how-do-i-forward-declare-an-inner-class) – 2015-07-15 09:34:07

回答

37

不能向前声明一样,嵌套类。

取决于你想要做什么,也许你可以使用一个命名空间,而不是在外层上的类。您可以转发,声明这样一类没有问题:

namespace Outer { 
    struct Inner; 
}; 

Outer::Inner* sweets; // Outer::Inner is incomplete so 
         // I can only make a pointer to it 

如果你的外在绝对必须是一个类,你不能鞋拔到一个命名空间,那么你所需要的外部是一个在您转发声明Inner的上下文中的完整类型。

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

没有,但是这有什么错

class Outer { 
public: //or protected or private 
    class Inner { 
    }; 

private: 
    Inner foo; 
}; 

正向声明没有意义在这里,除非我失去了一些东西(这是有可能看到你的问题是缺乏很多细节)

请记住,如果一个类被声明前,那么你只能申报前申报类型的对象或引用指针。你不能做任何事情,包括访问它的成员或功能。

+1

因为内在不是前向宣布它在那里完全定义。 – CashCow 2016-05-13 13:18:10

+0

如果您要在这里修改这些部分,该怎么办?也许公共部分中的某些函数使用私有变量,因此需要声明它们,但Inner也需要私有变量。我们如何让Inner在私人栏目中可见? – Sohaib 2017-05-29 12:23:43

1

如果一个类已经被前置声明(但你没有完整的定义还没有),那么你只能申报一个指向它,因为编译器还不知道班级的大小(也没有其领域或方法的名称)。

0

如果声明MaybeThatOtherWay类型的属性,而不是引用或指针,则编译器必须知道该类的完整定义才能确定外部类的大小。因此,不能使用前向声明和那种字段声明,无论它是否是嵌套类。

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

+3

不要使用双下划线 - 包含两个下划线的名称将保留给实施用于任何用途。请参阅http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier/228797#228797 – villintehaspam 2011-10-13 09:11:10

+0

这是我在这里面对的同样的问题吗? http://stackoverflow.com/questions/20214740/nested-class-as-a-template-parameter-of-parent-class-in-c – 2013-11-27 07:47:50

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