C++嵌套类在分离的头文件中

bou*_*bou 8 c++ nested

我想将嵌套类Inner从Outer.h移到一个单独的头文件中:

class Outer{
    class Inner{
    public:
        Inner(Outer& o){}
    };

public:
    Outer():i(*this){}
    ~Outer(){}
    Inner i;
};
Run Code Online (Sandbox Code Playgroud)

而对于'main.cpp'

#include "Outer.h"
int main(){
    Outer o;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是一旦我尝试将Inner类放在一个像这样的分隔头中:

class Outer{
    class Inner;

public:
    Outer():i(*this){}
    ~Outer(){};
    Inner i;
};
Run Code Online (Sandbox Code Playgroud)

并将Inner类放在'Inner.h'中,如下所示:

class Outer::Inner{
public:
    Inner(Outer& o){}
};
Run Code Online (Sandbox Code Playgroud)

并添加到主#include'Inner.h'中,如下所示:

#include "Outer.h"
#include "Inner.h"
int main(){
    Outer o;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我从编译器得到以下错误:Outer.h:10:9:错误:字段'i'的类型不完整.

我或多或少地了解为什么,但我找不到问题来实现我想做的事情.

Kir*_*rov 5

要创建Outer对象,必须知道类的内存布局,在这种情况下,它不是(完全是因为不完整Inner).

执行此操作的方法是使用指针,然后前向声明将起作用(因为指针具有固定大小,然后Outer将知道内存布局).


我的意思是:

// header file
class Outer{
    class Inner;

public:
    Outer();
    ~Outer();

    Inner* i;
};
Run Code Online (Sandbox Code Playgroud)

然后,在class的源文件中Outer,定义

// include header file for Outer and Inner classes

// source file
Outer::Outer()
{
    i = new Inner( *this );
};
Outer::~Outer()
{
    delete i;
};
Run Code Online (Sandbox Code Playgroud)

您需要在源文件中执行此操作,因为您需要include类的头文件Inner(您不能include直接在头文件中,因为您将遇到循环依赖(两个头文件将包含彼此),作为标题文件Inner还需要头文件Outer).


这也称为pImpl idiom - "指向实现的指针",通常Inner被调用Impl,成员pImpl或类似的东西,取决于使用的编码约定.我们的想法是隐藏任何实现细节,例如私有/受保护成员(函数,数据).