あるレベルのコントローラーの「親」クラスが多数の「子」クラスの作成/指示を担当する階層クラス構造を探しています。親クラスは、作成する各子を直接参照できる必要があり、各子はその親を直接参照できる必要があります(この子が他のクラスの親でもない場合は、その親のみ)。これにより、親を介して兄弟を参照できます。このパラダイムは、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_*/
この実装は、メッセージを子オブジェクトに正常にブロードキャストし、次のように子オブジェクトから親クラスへのコールバックを実行できるという点でほぼ機能します。
TreeRoot.cpp
...
a->someChildMethod();
a->getRootScene()->someParentMethod();
しかし、私が次のことを試してみると:
ChildA.cpp
...
rootScene->someParentMethod(); //ERROR C2027: use of undefined type TreeRoot
未定義の型エラーが発生します。上記のように前方宣言を使用しても、TreeRootが実際に何であるかはコンパイラに通知されないため、これは理にかなっています。問題は、上記のrootScene-> someParentMethod()呼び出しのような子オブジェクトからの呼び出しを有効にするにはどうすればよいですか?おそらく、テンプレートを介してジェネリック型を使用すると、コンパイラーが満足し、私が探している機能を提供できるでしょうか?
ありがとう、CCJ