我正在寻找一个分层的类结构,其中一个级别的控制器“父”类负责创建/指导许多“子”类。父类应该能够直接引用它创建的每个子类,并且每个子类应该能够直接引用它的父类(并且,假设这个子类不是更多类的父类,只是它的父类)。这允许通过父级引用兄弟姐妹。我发现这种范例在 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__
子类 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__
子类 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_*/
该实现几乎可以正常工作,因为我可以成功地将消息广播到子对象并执行从子对象到父类的回调,如下所示:
树根.cpp
...
a->someChildMethod();
a->getRootScene()->someParentMethod();
但是,当我尝试以下操作时:
子A.cpp
...
rootScene->someParentMethod(); //ERROR C2027: use of undefined type TreeRoot
我得到一个未定义的类型错误。这是有道理的,因为使用上面的前向声明并不会告知编译器 TreeRoot 的实际含义。那么问题是如何启用来自子对象的调用,例如上面的 rootScene->someParentMethod() 调用?也许通过模板使用泛型类型会使编译器满意并提供我正在寻找的功能?
谢谢,CCJ