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

时间:2014-02-20 08:37:06

标签: c++ nested

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

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

public:
    Outer():i(*this){}
    ~Outer(){}
    Inner i;
};

对于'main.cpp'

#include "Outer.h"
int main(){
    Outer o;
    return 0;
}

但是一旦我尝试将Inner类放在一个单独的标题中,就像这样:

class Outer{
    class Inner;

public:
    Outer():i(*this){}
    ~Outer(){};
    Inner i;
};

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

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

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

#include "Outer.h"
#include "Inner.h"
int main(){
    Outer o;
    return 0;
}

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

我或多或少地明白为什么,但我找不到实现我想要做的事情。

2 个答案:

答案 0 :(得分:5)

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

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


我的意思是:

// header file
class Outer{
    class Inner;

public:
    Outer();
    ~Outer();

    Inner* i;
};

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

// include header file for Outer and Inner classes

// source file
Outer::Outer()
{
    i = new Inner( *this );
};
Outer::~Outer()
{
    delete i;
};

您需要在源文件中执行此操作,因为您需要includeInner的头文件(您不能直接include在头文件中,因为您' ll遇到循环依赖(两个头文件将相互包含),因为Inner的头文件也需要Outer的头文件。


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

答案 1 :(得分:1)

如果您不想将i成员转换为指针,最好的选择是将Inner的定义移到Outer之外,并使用命名空间进行嵌套。

请注意,在这种情况下,您需要在Inner.h定义之前添加Outer标头。