外部类的嵌套类定义,而外部类包含内部类的实例

Nested class definition outside outer class's, while outer class contains instance of inner class

本文关键字:外部 内部类 包含 实例 定义 嵌套      更新时间:2023-10-16

C++

如果外部类至少有一个内部类的实例作为数据成员,我如何将内部(嵌套)类的定义放在其外部(封闭)类定义之外?我搜索了一下,但我找到的最相关的SO答案,源文件中的嵌套类定义,没有外部类将内部对象作为数据成员的示例。我遵循了这个答案,就在外部类的定义中声明但不定义内部类而言,但我的代码仍然是坏的:

struct Outer
{
    struct Inner;
    Inner myinner;
    Outer() : myinner(2) {}
};
struct Outer::Inner
{
    Inner(int n) : num(n) {}
    int num;
};
int main()
{
    Outer myouter;
}

给出了VC11中的错误CCD_ 1。

为什么断开的代码没有与Outer的定义中定义Inner的版本等效的效果,就像下面的工作代码一样?

struct Outer
{
    struct Inner
    {
        Inner(int n) : num(n) {}
        int num;
    } myinner;
    Outer() : myinner(2) {}
};

这是一个危险信号,但您可以使用假模板。

template< typename = void >
struct Outer_temp
{
    struct Inner;
    Inner myinner;
    Outer_temp() : myinner(2) {}
};
typedef Outer_temp<> Outer; // Hide template from user.
template< typename v >
struct Outer_temp< v >::Inner
{
    Inner(int n) : num(n) {}
    int num;
};
int main()
{
    Outer myouter;
}

模板中的Inner是一个依赖类型,因此在成员或任何其他上下文中定义实例时,它不需要是完整的。它只需要在实例化发生后完成,在本例中是从main开始。

我想不出有什么好的理由这样做,但事实确实如此。

嵌套类不应该为了程序组织而使用。嵌套暗示了一种概念依赖,即"内部不能存在,除非在外部提供的上下文中。"尽管例如,容器节点类嵌套在容器中是很常见的,但这可能会导致问题。SCARY习语是一种设计风格,它否定了这种组织,并获得了改进的通用性。

TL;DR:独立定义这两个类,并用嵌套的typedef将它们链接起来。