池尾:そういうふうに考えてい探店のオブジェク由来のものに関する共通インターフェースに共通コンテナ?

StackOverflow https://stackoverflow.com/questions/2489533

質問

思管理気象派生クラスから共有スクラス共通します。

を説明するために問題ということか僕はビルゲームをすることができます異なる俳優たち。呼び界面 IActor を求めることができる EnemyCivilian からです。

今の私のゲームのメインループにできること:

// somewhere during init
std::vector<IActor> ActorList;
Enemy EvilGuy; 
Civilian CoolGuy;
ActorList.push_back(EvilGuy);
ActorList.push_back(CoolGuy);

// main loop
while(!done) {
    BOOST_FOREACH(IActor CurrentActor, ActorList) {
        CurrentActor.Update();
        CurrentActor.Draw();
    }
}

...なされるようになっています。この例では、明らかになったのですが、ここではその理由をいいます。

教えてください:池尾:そういうふうに考えていで安全性の高い、最高レベルを管理する方法それらのオブジェクトに共通の不均質コンテナ?知って様々なアプローチ(ブ::はvoid*,ハンドラクラスブー::shared_ptr,進みました。ポインターコンテナdynamic_castができない決定をするにはこちらをご覧ください。

もんであることを強調したいな場所には近づかないでくださいなどのマニュアルメモリ管理や入れ子のポインタ.

援よろしくお願いいたします:).

役に立ちましたか?

解決

あなたはポインタとしてオブジェクトを格納する必要が推測しているとして。
私は、ブーストポインタのコンテナ(というよりもスマートポインタの通常のコンテナ)を使用することを好むます。

彼らは、オブジェクト(帰国参照)のではなく、ポインタであるかのように

は、この理由は、オブジェクトブーストPTRコンテナへのアクセスです。これは、それが簡単にコンテナに標準ファンクタやアルゴリズムを使用できるようになります。

スマートポインタの欠点は、あなたが所有権を共有しているということである。
これは、あなたが本当に欲しいものではありません。あなたは、所有権は、単一の場所(この場合はコンテナ)になりたい。

boost::ptr_vector<IActor> ActorList; 
ActorList.push_back(new Enemy()); 
ActorList.push_back(new Civilian());

std::for_each(ActorList.begin(), 
              ActorList.end(),
              std::mem_fun_ref(&IActor::updateDraw));

他のヒント

問題を解決する先ほども少し触れましたが、がんの方向性も確認することができます。こだことが必要なの

  • を定義する基底クラス(までの間ですでに実施している)と仮想関数をオーバーライドする導出クラス EnemyCivilian おます。
  • を選定するために必要な適切なコンテナのまま保存オブジェクトです。を取った std::vector<IActor> はせが
    • まずきの追加オブジェクトのベクターでドラッグ&ドロップするスライスオブジェクト.このことのみを IActor の一部 Enemy または Civilian が格納されるようになっていくのオブジェクトです。
    • 第二に必要な関数の呼び出しによってオブジェクトの型(virtual functionsできれば利用のポインタ.

両方の理由上記のポイントと利用する必要がありコンテナを含むことができポインタのようなもの std::vector<IActor*> .がより良い選択を使う container of smart pointers を節約することができますからメモリ管理なります。を利用できますのスマートポインタ、ご気軽にお問い合わせ下さが必要なもの auto_ptr)

このコードのようになり

// somewhere during init
std::vector<some_smart_ptr<IActor> > ActorList;
ActorList.push_back(some_smart_ptr(new Enemy()));
ActorList.push_back(some_smart_ptr(new Civilian()));

// main loop
while(!done) 
{
    BOOST_FOREACH(some_smart_ptr<IActor> CurrentActor, ActorList) 
    {
        CurrentActor->Update();
        CurrentActor->Draw();
     }
}

ですが、ここでは同様のオリジナルのコード以外のスマートポインタ部

マイインスタント反応を使用すると、コンテナ内のスマートポインタを格納し、そしてあなたが派生クラスにdynamic_castバックに必要ないことを十分に確認してください、基本クラスを定義(純粋)仮想メソッドをしなければならないということです。

あなたが排他的に要素を所有するコンテナをしたい場合は、ブーストポインタのコンテナを使用します。彼らはその仕事のために設計されています。それ以外の場合は、shared_ptr<IActor>のコンテナを使用します(もちろん株式所有用途のshared_ptrする必要があることをすべての人を意味し、適切にそれらを使用する)。

どちらの場合も、IActorのデストラクタが仮想であることを確認してください。

それはアウトですので void*は、手動メモリ管理を行うために必要があります。タイプは、継承によって関連しているときBoost.Anyは行き過ぎです - 標準多型は、仕事をしていません。

あなたがdynamic_castたりする必要がないかどうか直交問題がある - コンテナのユーザだけIActorインタフェースを必要とし、あなたはどちらか()、または他の、仮想インターフェイスのすべての機能を作る(b)の非を使用している場合仮想インターフェイスのイディオムは、あなたはdynamic_castをする必要はありません。もしIActorオブジェクトのいくつかは「本当に」民間人であり、IActor民間インタフェースではなく、あるものを利用したいというコンテナノウハウのユーザーは、その後、あなたがキャスト(または再設計)が必要になります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top