C ++无法建立对“父”对象的句柄引用 – 循环包含或未定义的类型错误

我希望有一个层次结构的类结构,其中一级控制器“父”类负责创建/指导一些“子”类。 父类应该能够引用它直接创建的每个子节点,并且每个子节点应该能够引用它的父节点(并且,假设这个子节点也不是更多类的父节点,只有它的父节点)。 这允许通过父级引用兄弟姐妹。 我发现这个范例在Java和C#等JIT编译语言中很有用,但是C ++提出了一个独特的问题……

我第一次尝试实现这个范例如下:

父类TreeRoot.h

#ifndef __CCPP_SCENE_H__ #define __CCPP_SCENE_H__ #include "ChildA.h" #include "ChildB.h" class TreeRoot : { private: ChildA* a; ChildB* b; public: //member getters ChildA* getA(); ChildB* getB(); }; #endif // __CCPP_SCENE_H__ 

Child class ChildA.h

 #ifndef CHILDA_H_ #define CHILDA_H_ #include "TreeRoot.h" class ChildA { private: TreeRoot* rootScene; public: ChildA(TreeRoot*); ~ChildA(void); TreeRoot* getRootScene(); void setRootScene(TreeRoot*); }; #endif /*CHILDA_H_*/ 

子类ChildB.h

 #ifndef CHILDB_H_ #define CHILDB_H_ #include "TreeRoot.h" class ChildB { private: TreeRoot* rootScene; public: ChildB(TreeRoot*); ~ChildB(void); TreeRoot* getRootScene(); void setRootScene(TreeRoot*); }; #endif /*CHILDB_H_*/ 

现在当然因为循环包含而无法编译(TreeRoot.h包含ChildA.h和ChildB.h,它们都包含TreeRoot.h等)所以我尝试使用前向声明:

父类TreeRoot.h

 #ifndef __CCPP_SCENE_H__ #define __CCPP_SCENE_H__ #include "ChildA.h" #include "ChildB.h" class TreeRoot : { private: ChildA* a; ChildB* b; public: //member getters ChildA* getA(); ChildB* getB(); }; #endif // __CCPP_SCENE_H__ 

Child class ChildA.h

 #ifndef CHILDA_H_ #define CHILDA_H_ //#include "TreeRoot.h" //can't use; circular include! class TreeRoot; class ChildA { private: TreeRoot* rootScene; public: ChildA(TreeRoot*); ~ChildA(void); TreeRoot* getRootScene(); void setRootScene(TreeRoot*); }; #endif /*CHILDA_H_*/ 

子类ChildB.h

 #ifndef CHILDB_H_ #define CHILDB_H_ //#include "TreeRoot.h" //can't use; circular include! class TreeRoot; class ChildB { private: TreeRoot* rootScene; public: ChildB(TreeRoot*); ~ChildB(void); TreeRoot* getRootScene(); void setRootScene(TreeRoot*); }; #endif /*CHILDB_H_*/ 

该实现几乎可以工作,因为我可以成功地将消息广播到子对象,并执行从子对象到父类的回调,如下所示:

TreeRoot.cpp

 ... a->someChildMethod(); a->getRootScene()->someParentMethod(); 

但是,当我尝试以下内容时:

ChildA.cpp

 ... rootScene->someParentMethod(); //ERROR C2027: use of undefined type TreeRoot 

我得到一个未定义的类型错误。 这是有道理的,因为如上所述使用前向声明不会通知编译器TreeRoot实际上是什么。 那么问题是我如何启用来自子对象的调用,如上面的rootScene-> someParentMethod()调用? 也许通过模板使用generics类型可以使编译器满意并提供我正在寻找的function?

谢谢,CCJ

在所有.h文件中使用前向声明。 您可以这样做,因为您只将指针存储为类成员,因此您不需要完整的类声明。

然后,在所有相应的.cpp文件中, #include包含所需类的头文件。

因此,在TreeRoot.h您转发声明ChildAChildB 。 在TreeRoot.cpp ,您需要#include ChildA.hChildB.h

冲洗并重复其他2个课程。

请注意,这将解决您当前的问题,但这种设计充其量只是片状。

您可以尝试在ChildA和ChildB文件中包含’TreeRoot.h’。 我还建议使用Polymorphism并创建一个父类,A和Binheritance它,用于共享行为。

这不涉及摆弄头文件,但我的建议是:要么让所有节点都成为同一个类(使更多的灵活性[如果你决定要将树变成另一棵树的子树怎么办?你必须将根节点的类从第一个树改为子类],至少在我看来,更有意义/似乎更优雅/会减少你必须编写的代码量和/或简化代码),或者为父节点类和子节点类使用超类(如ATaylor所建议的那样),尽管我觉得如果你的父节点和子节点有很多不同的function,只有形成它们所需的function,那将只是一个更好的解决方案。树的结构。

在ChildA.cpp文件中,您必须包含父标题

 #include "TreeRoot.h"