タスクシステムについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ジャーニー

タスクシステムについて

#1

投稿記事 by ジャーニー » 15年前

お久しぶりです.
今回は今すぐに必要なことではないのですが今後のために質問したいことがあります.
class BaseObject
{
public:
virtual void Update()=0;//オブジェクト更新メソッド
virtual void DrawUpdate()=0;//描画用更新メソッド
virtual void DrawGraph()=0;//描画
};
例えば上のような仮想クラスがあったとして,これを継承したクラス(例えばCとします)を作ります.
BaseObject *bo = new C();といったように作ります.


これを以下のようなオブジェクト更新タスク,描画用タスクに渡します
list<BaseObject*> ObjectTask;
list<BaseObject*> DrawTask;

ObjectTask.push_back(bo);
DrawTask.push_back(bo);

1つのクラスで様々なタスクに対応できる作りにします.
描画はしないけどオブジェクトは更新するという場合にはDrawTaskからだけ外します.
このときDrawTaskから外したとき,ObjectTaskでboを使うのは問題ないのでしょうか.
一応簡単なテストを行った時動作には問題なさそうでしたが問題点などがあった場合教えてください.

また,この方法を実際ゲームなどに組み込む時に問題がないか,別の方法などがあれば教えてください.
抽象的な質問ですがよろしくお願いします.

御津凪

Re:タスクシステムについて

#2

投稿記事 by 御津凪 » 15年前

タスクシステムとしての機能は十分だと思いますが、
使用済みタスクを解放する場合の対処はどう考えていますか?

単に解放するだけだと、どこかでまだ使用されていたりすることをきちんと考慮しないとバグの原因になりやすいです。

そのため、 BaseObject に参照カウントをつける、つまり boost::shared_ptr の様なポインタクラスなどで
包括して使用すると、管理が楽になりますよ。

あと、実行順序と描画順序は操作(入れ替えたり先頭・末尾に移動させるなど)できるようにすると
なお良いでしょう。

ジャーニー

Re:タスクシステムについて

#3

投稿記事 by ジャーニー » 15年前

回答ありがとうございます.

一応全てのオブジェクトを保持するものを別に用意しようと考えていました.
shared_ptrですがboostを説明しているサイトによるとどの変数からも参照されなくなると解放されるとあるのですが,具体的にどのような状態になると解放されるのでしょうか?

御津凪

Re:タスクシステムについて

#4

投稿記事 by 御津凪 » 15年前

具体的に示すならコードで書いた方がいいと思ったので書いてみました。
#include <boost/shared_ptr.hpp>
#include <stdio.h>

class C {
public:
    C( const char* inNname ):pName(inNname){
        printf("instance new   [%s].\n", inNname);
	}
    ~C( void ){
        printf("instance delete[%s].\n", pName);
    }

private:
    const char* pName;
};
typedef boost::shared_ptr<C> SP_C; // 短くするために typedef 。


void test_shared1( const char* inName ){
    printf("test_shared1 func begin.\n");
    SP_C sp_cb(new C(inName));
    printf("test_shared1 func end.\n");
}
void test_shared2( const char* inName, SP_C& outPtr ){
    printf("test_shared2 func begin.\n");
    SP_C sp_cb(new C(inName));
    outPtr = sp_cb;
    printf("test_shared2 func end.\n");
}

int main( void ){
    printf("main func begin.\n");
    SP_C sp_ca(new C("A"));

    printf("call test_shared1.\n");
    test_shared1("B");
    printf("call test_shared2.\n");
    test_shared2("C", sp_ca);

    printf("main func end.\n");
    return 0;
}
下記が実行結果です。
main func begin.
instance new   [A].
call test_shared1.
test_shared1 func begin.
instance new   .
test_shared1 func end.
instance delete.
call test_shared2.
test_shared2 func begin.
instance new   [C].
instance delete[A].
test_shared2 func end.
main func end.
instance delete[C].

コードと実行結果を見比べるとわかると思います。

ジャーニー

Re:タスクシステムについて

#5

投稿記事 by ジャーニー » 15年前

コード例まで書いていただいてありがとうございます.
そのアドレスに参照することがなくなった瞬間に破棄されるみたいですね.
かなり便利そうなのでboostの勉強もやってみます.
ありがとうございました.

GPGA

Re:タスクシステムについて

#6

投稿記事 by GPGA » 15年前

>問題点などがあった場合教えてください
継承元で変数を宣言し、継承先でnewをした場合
BaseObjectに仮想デストラクタを用意しないと、deleteするときにデストラクタが呼ばれません。
{
  C c;
} // デストラクタが呼ばれる

{
  C* c = new C();
  delete c; // デストラクタが呼ばれる
}
{
  BaseObject* c = new C();
  delete c; // デストラクタが呼ばれない
}

ジャーニー

Re:タスクシステムについて

#7

投稿記事 by ジャーニー » 15年前

>GPGAさん
返事が遅くなりましたすいません.
仮想デストラクタについては質問する際突貫で作ったので忘れていました.
実際に作るときにはデストラクタは作成します

閉鎖

“C言語何でも質問掲示板” へ戻る