我是新手并学习C ++,这段代码是一个有效的C ++实现,请参阅下面的代码,
// FoomImpl.h
#include "Foo.h"
namespace FooFoo { namespace Impl {
class FooImpl
{
public:
FooImpl( FooFoo::CFoo::stBar bar )
{
m_bar = bar;
}
private:
FooFoo::CFoo::stBar m_bar;
};
} }
// Foo.h
#include "FoomImpl.h"
namespace FooFoo {
class CFoo
{
public:
struct stBar
{
int aBar;
};
public:
CFoo( stBar bar ) : impl(NULL)
{
impl = new FooFoo::Impl::FoomImpl( bar );
}
CFoo( ) : impl(NULL){}
~CFoo( )
{
if(impl)
delete impl;
}
private:
FooFoo::Impl::FoomImpl *impl;
};
}
非常感谢。
答案 0 :(得分:1)
不,需要前向声明,因为您有循环依赖。
答案 1 :(得分:1)
你不能让两个不同的对象相互堆叠在堆栈上,因为当编译器遍历一个对象的头文件时,它现在需要所有它的数据成员的大小,以便知道对象本身的大小。在你的情况下显然是不可能的。
你可以这样做的方法是将你的CFoo构造函数移动到cpp文件中,然后在类上面的Foo.h中编写class Impl::FoomImpl;
。这称为前瞻性声明。它只是告诉编译器这是一个类名。这足以使用指向该类的指针。现在Foo.h不再需要包含FoomImpl.h,因为它只使用指向Impl::FoomImpl
的指针,该指针具有已知大小(最可能是4个字节)。
如果您在某个名称空间内,则无需指定范围...
namespace FooFoo
{
//no need to use "FooFoo::" here
}
为了避免进一步的混淆,我建议你保留命名空间的数量。除非您正在开发一个将由其他开发人员使用的库,否则即使您的类名明确无误,也几乎不会使用任何库。就个人而言,在最终用户软件中,我只使用它们来确定范围,我给我的课程提供了非常明确和具体的名称。