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

发布于 2024-08-28 07:22:34 字数 292 浏览 6 评论 0原文

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

IE

class Outer;

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

class Outer
{
 MaybeThisWay x;

 class MaybeThatOtherWay;

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

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.

class Outer;

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

class Outer
{
 MaybeThisWay x;

 class MaybeThatOtherWay;

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

冬天旳寂寞 2024-09-04 07:22:34

您不能像这样向前声明嵌套类。

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

namespace Outer {
   struct Inner; 
};

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

如果你的 Outer 绝对必须是一个类,并且你不能将它硬塞到命名空间中,那么你需要 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

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.

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
物价感观 2024-09-04 07:22:34

如果没有完全指定包含类,则无法转发声明嵌套类。这个小技巧有点解决了这个问题,但这

class Outer_Inner
{
};

class Outer
{
public:
   typedef Outer_Inner Inner;
};

对我来说很有效,因为在我的命名约定中 Outer_Inner 不是一个有效的类名,所以很明显它指的是一个嵌套类。

您仍然无法像这样向前声明嵌套类:

class Outer::Inner;

但至少可以使用以下方式向前声明:

class Outer_Inner;

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

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_Inner isn't a valid class name, so it's obvious that it refers to an nested class.

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.

渡你暖光 2024-09-04 07:22:34

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

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).

蓝海似她心 2024-09-04 07:22:34

不,但是前向声明的问题

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

private:
    Inner foo;
};

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

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

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.

久夏青 2024-09-04 07:22:34

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

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.

帅的被狗咬 2024-09-04 07:22:34

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

接口:

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

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());
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文