我想在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'的类型不完整。
我或多或少地明白为什么,但我找不到实现我想要做的事情。
答案 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;
};
您需要在源文件中执行此操作,因为您需要include
类Inner
的头文件(您不能直接include
在头文件中,因为您' ll遇到循环依赖(两个头文件将相互包含),因为Inner
的头文件也需要Outer
的头文件。
这也称为 pImpl idiom - “指向实现的指针”,Inner
通常称为Impl
,成员pImpl
或类似的东西,取决于使用的编码约定。我们的想法是隐藏任何实现细节,例如私有/受保护成员(函数,数据)。
答案 1 :(得分:1)
如果您不想将i
成员转换为指针,最好的选择是将Inner
的定义移到Outer
之外,并使用命名空间进行嵌套。
请注意,在这种情况下,您需要在Inner.h
定义之前添加Outer
标头。