我希望有一个层次结构的类结构,其中一级控制器“父”类负责创建/指导一些“子”类。 父类应该能够引用它直接创建的每个子节点,并且每个子节点应该能够引用它的父节点(并且,假设这个子节点也不是更多类的父节点,只有它的父节点)。 这允许通过父级引用兄弟姐妹。 我发现这个范例在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
您转发声明ChildA
和ChildB
。 在TreeRoot.cpp
,您需要#include
ChildA.h
和ChildB.h
。
冲洗并重复其他2个课程。
请注意,这将解决您当前的问题,但这种设计充其量只是片状。
您可以尝试在ChildA和ChildB文件中包含’TreeRoot.h’。 我还建议使用Polymorphism并创建一个父类,A和Binheritance它,用于共享行为。
这不涉及摆弄头文件,但我的建议是:要么让所有节点都成为同一个类(使更多的灵活性[如果你决定要将树变成另一棵树的子树怎么办?你必须将根节点的类从第一个树改为子类],至少在我看来,更有意义/似乎更优雅/会减少你必须编写的代码量和/或简化代码),或者为父节点类和子节点类使用超类(如ATaylor所建议的那样),尽管我觉得如果你的父节点和子节点有很多不同的function,只有形成它们所需的function,那将只是一个更好的解决方案。树的结构。
在ChildA.cpp文件中,您必须包含父标题
#include "TreeRoot.h"
以上就是c/c++开发分享C ++无法建立对“父”对象的句柄引用 – 循环包含或未定义的类型错误相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/523200.html