2012-02-27 8 views
1

私はこの上でC++übern00bに行き、継承があるときに循環依存を処理する最良の方法がどのようになるか尋ねます。継承に循環依存関係を扱う

セットはシンプルです:シーンクラスはActorを拡張します。シーンには、アクタのベクトルへのポインタがあります。 Actorには(親)Sceneのポインタがあります。

Scene.h:

#include <string> 
#include <vector> 
using namespace std; 

#ifndef __Scene_h__ 
#define __Scene_h__ 

#include "Actor.h" 

namespace myns 
{ 
    // class Actor; 
    class Scene; 
} 

namespace myns 
{ 
    class Scene: public myns::Actor 
    { 
     /* private class attributes... */ 

     public: 
      /* public class attributes... */ 

      std::vector<myns::Actor*> actors; 

      Scene(/* arguments */); 

      /* public class methods... */ 
    }; 
} 

#endif 

Actor.h

#include <string> 
#include <vector> 
using namespace std; 

#ifndef __Actor_h__ 
#define __Actor_h__ 

#include "Scene.h" 

namespace myns 
{ 
    // class Scene; 
    class Actor; 
} 

namespace myns 
{ 
    class Actor 
    { 
     /* private class attributes... */ 

     public: 
      /* public class attributes... */ 

      myns::Scene* scene; 

      Actor(); 

      Actor(/* arguments */); 

      /* public class methods... */ 
    }; 
} 

#endif 

しかし、これはC2504エラー/ベースクラスのたくさんビジュアルに未定義の私を与えるためとして

は、私が得たファイルを含めますStudio 2010.

Actor.hのScene.hのインクルードにコメントして、 Actor.h上のシーンの明確化、それは動作しますが、私のアプリケーションでは、Actor.hだけを特定のコードに含めると機能しません。以前は手動でScene.hを含める必要なしにActor.hを含むActor.hの包含関係を維持しながら、これをどのように動作させることができますか?

私のクラス定義には何が問題なのですか?この循環依存関係を処理する最良の方法は?

#ifndefディレクティブはこの組み込みの問題を防ぐことはできませんか?

ありがとうございます。

答えて

6

が、私は、コードの特定の部分にのみActor.hを含めたい場合は、その後、私のアプリでは、それはあなたがする必要がどのような

を動作しません.cppファイルでありますあなたがを使用する必要があるファイルActorクラスを定義するには、include Actor.h Scene.hの両方を指定する必要があります。そうすれば、前方宣言が解決され、すべてがうまくいくはずです。

脇に#ifndef#defineincludeの前にファイルの先頭に移動する必要があります。また、ヘッダーファイルにusingがあることは、他のファイルのincludeが正しく動作しない可能性があるため、悪い習慣です。あなたのnamespace myns { ... }の中に入れても大丈夫です。

+0

Actor.h(Actor.hが依存関係を気にする必要がある)だけが必要なときに、Actor.hを含めることができるようにクラスを宣言できる方法はありますか? この依存関係の委任は標準的なC++のプラクティスですか? これらのすべてのクラスがライブラリの一部であると仮定すると、これらのすべてを適切な順序で、次にLibray.hを含む私のアプリケーションに含めるLibrary.hを作成することをお勧めしますか? – pedrosanta

+1

Act.cで除いて 'Actor'を使うために両方のファイルを含める必要がある状況は本当にありません。そうしないとActor.hで' Scene'を使うことになります。 veは前方宣言しか得ていない。 – spencercw

+0

ああ、私は最後のコメントを持っています。はい、それは意味があり、よく指摘されています。 – pedrosanta

1

シーンは本当に俳優のタイプですか?

もしそうなら、俳優はおそらくシーンについて知ってはいけません。基本クラスは、通常、派生クラスについては知ってはいけません。

ここでLiskov Substitution Principleはどこですか?シーンによって異なる多面的に実行される俳優に対して、どのようなアクションを実行しますか?

シーンは、アクタから派生するので、その基本クラスを含める必要があります。しかし、Actor.hでは、本当にSceneクラスが必要な場合は前方宣言のみでなければなりません。

コンパイル単位(.cppファイル)には、必要に応じて両方のヘッダーを含めることができます。

+0

名前空間はタイプミスです。 :)修正されました。 – pedrosanta

+0

シーンは俳優(私は表現や行動/バックステージアクションなどの俳優プロパティが必要です)を拡張するので、(スーパー)俳優の特別な種類です。しかし、やはり俳優がシーンに配置され、それとコミュニケートする必要があります(シーンを終了するなど)。 私はその原則をチェックして、あなたに連絡します。 – pedrosanta

関連する問題