C++ 嵌套类/前向声明问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2600385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:02:25  来源:igfitidea点击:

C++ nested class/forward declaration issue

c++forward-declarationnested-class

提问by uj2

Is it possible to forward-declare a nested class, then use it as the type for a concrete (not pointer to/reference to) data member of the outer class?

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

I.E.

IE

class Outer;

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

class Outer
{
 MaybeThisWay x;

 class MaybeThatOtherWay;

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

回答by janks

You can't forward-declare a nested class like that.

你不能像这样向前声明一个嵌套类。

Depending on what you're trying to do, maybe you can use a namespace rather than a class on the outer layer. You can forward-declare such a class no problem:

根据您尝试执行的操作,也许您可​​以在外层使用命名空间而不是类。你可以向前声明这样一个类没问题:

namespace Outer {
   struct Inner; 
};

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

If your Outer absolutely must be a class, and you can't shoe-horn it into a namespace, then you'll need for Outer to be a complete type in the context where you forward declare Inner.

如果您的 Outer 绝对必须是一个类,并且您不能将它硬塞进一个命名空间,那么您将需要 Outer 在您转发声明 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

回答by deft_code

There is no way to forward declare a nested class without fully specifying the containing class. This little trick kinda fixes the problem though

如果不完全指定包含类,就无法转发声明嵌套类。这个小技巧虽然解决了这个问题

class Outer_Inner
{
};

class Outer
{
public:
   typedef Outer_Inner Inner;
};

This works for me as in my naming convention Outer_Innerisn't a valid class name, so it's obvious that it refers to an nested class.

这对我有用,因为在我的命名约定Outer_Inner中不是有效的类名,因此很明显它指的是嵌套类。

You still can't forward declare the nested class like this:

您仍然无法像这样转发声明嵌套类:

class Outer::Inner;

But at least it can be forward declared with:

但至少它可以通过以下方式进行前向声明:

class Outer_Inner;

If you don't like the way Outer_Inner looks you could adopt a naming convention for nested classes that better suits your tastes. Outer__Inner, Outer_nested_Inner, etc.

如果您不喜欢 Outer_Inner 的外观,您可以采用更适合您口味的嵌套类的命名约定。 Outer__InnerOuter_nested_Inner等等。

回答by Glen

No, but what's wrong with

没有,但是有什么问题

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

private:
    Inner foo;
};

Forward declaring doesn't make sense here, unless I'm missing something (which is possible seeing as your question is lacking in a lot of details)

向前声明在这里没有意义,除非我遗漏了一些东西(这可能是因为你的问题缺少很多细节)

Remember, if a class is forward declared then you can only declare references to or pointers to an object of the forward declared type. You can't do anything else with it, including accessing it's members or functions.

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

回答by Ken Bloom

If a class has been forward-declared (but you don't have the full definition yet) then you can only declare a pointer to it, because the compiler doesn't yet know the size of the class (nor the names of its fields or methods).

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

回答by Seb

If you declare an attribute of type MaybeThatOtherWay, not a reference nor a pointer, the compiler must know the full definition of the class to determine the size of the outer class. Thus, you can't use forward declaration and that kind of field declaration, whether it's a nested class or not.

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

回答by zzz777

If you just need a type as a function parameter or static variable, it could be done on the client side. For example, to receive event notification from Outer:

如果您只需要一个类型作为函数参数或静态变量,则可以在客户端完成。例如,从外部接收事件通知:

Interface:

界面:

class Client {
public:
private:
    static void gotIt(int event);
    class Helper;
};

Implementation:

执行:

#include <outer.hpp>

class Client::Helper {
public:
    static void fromOuter(Outer::Inner const& inner) 
    { 
        gotIt(inner.event());
    }
};