0

我正在寻找一个分层的类结构,其中一个级别的控制器“父”类负责创建/指导许多“子”类。父类应该能够直接引用它创建的每个子类,并且每个子类应该能够直接引用它的父类(并且,假设这个子类不是更多类的父类,只是它的父类)。这允许通过父级引用兄弟姐妹。我发现这种范例在 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

4

4 回答 4

2

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

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

所以,在TreeRoot.h你前向声明ChildAand ChildB。在TreeRoot.cpp,你#include ChildA.hChildB.h

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

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

于 2012-08-06T16:31:33.510 回答
1

这不涉及摆弄头文件,但我的建议是:要么让所有节点成为同一个类(实现更大的灵活性[如果你决定要将一棵树变成另一棵树的子树怎么办?你必须将根节点的类从第一棵树更改为子类],并且至少在我看来,更有意义/看起来更优雅/会减少和/或简化您必须编写的代码的数量),或者对父节点和子节点类都使用超类(正如 ATaylor 建议的那样),尽管我认为只有当您的父节点和子节点具有很多不同的功能时,这才是更好的解决方案树状结构。

于 2012-08-06T16:30:07.030 回答
1

您可以尝试在 ChildA 和 ChildB 文件中包含“TreeRoot.h”。我还建议使用多态性并创建一个 A 和 B 继承自的父类,以实现共享行为。

于 2012-08-06T16:29:31.167 回答
0

在 ChildA.cpp 文件中,您必须将父标头包含为

#include "TreeRoot.h"
于 2012-08-06T16:30:37.660 回答