インスタンスをリサイクルするのはスマートではないでしょうか?

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
taketoshi
記事: 222
登録日時: 14年前
住所: 日本国

インスタンスをリサイクルするのはスマートではないでしょうか?

#1

投稿記事 by taketoshi » 12年前

こんばんわ。

プログラミングの設計についてお尋ねしたいことがあります。
敵クラスや弾丸クラス等、同じようなオブジェクトを複数扱うとき
敵や弾丸が消滅したらインスタンスもdeleteするべきなのでしょうか?
パラメータ関係を再度初期化してリサイクルし出現させるって方法はあまりスマートではない気がしています。

このようなプログラムを組むとき、敵や弾丸にそってインスタンスも消滅させ
次に出現するときはインスタンスを作り直すのがよいのか

どちらの方が設計的に理にかなっているのかご指導ください。

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: インスタンスをリサイクルするのはスマートではないでしょうか?

#2

投稿記事 by h2so5 » 12年前

インスタンスを作り直すように設計したほうが簡単だと思います。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: インスタンスをリサイクルするのはスマートではないでしょうか?

#3

投稿記事 by softya(ソフト屋) » 12年前

私も簡単でバグの減る方はどっちかで考えるべきだと思います。
画像ハンドルを保持している場合は、画像ハンドルは別クラスで管理しましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

beatle
記事: 1281
登録日時: 13年前
住所: 埼玉
連絡を取る:

Re: インスタンスをリサイクルするのはスマートではないでしょうか?

#4

投稿記事 by beatle » 12年前

newでインスタンスを作りなおすと、素直で分かりやすくなるけどnewのせいで遅くなる
インスタンスを再度初期化して使いまわすと、newを使わない分速くなるけど分かりにくくなる

というので悩んでいるのであれば、配置newを検討してみてはいかがでしょうか。
普通のnewを使うときの分かりやすさと、newを使わない速さを両立できるのではと思います。

インスタンスを使いまわすときは、恐らくインスタンスの配列があって、その配列の中から現在使われていないインスタンスを探し、そのインスタンスを再初期化して使うんですよね。
この過程のうち「再初期化」の部分を配置newでやるわけですね。

配置newは、メモリ領域を新たに確保せず、既に存在するメモリ領域にインスタンスを配置します。
普通のnewは、new自身がmallocで確保した領域にコンストラクタを適用するのに対して、配置newは、ユーザーが指定した領域にコンストラクタを適用するものです。

taketoshi
記事: 222
登録日時: 14年前
住所: 日本国

Re: インスタンスをリサイクルするのはスマートではないでしょうか?

#5

投稿記事 by taketoshi » 12年前

皆さん返信ありがとうございます。
一般的な指針が理解できました。

>>beatleさん
こういった手法もあるんですね。勉強になります。

>インスタンスを使いまわすときは、恐らくインスタンスの配列があって
今までこういった手法でやっていたので、配置newの概念も理解できました。

ありがとうございます。解決とさせていただきます。
最後に編集したユーザー taketoshi on 2013年2月26日(火) 21:18 [ 編集 1 回目 ]

taketoshi
記事: 222
登録日時: 14年前
住所: 日本国

Re: インスタンスをリサイクルするのはスマートではないでしょうか?

#6

投稿記事 by taketoshi » 12年前

すいません、ひとつ質問があります

softyaさんの発言に対してなのですが
>画像ハンドルを保持している場合は、画像ハンドルは別クラスで管理しましょう。

これはどのように実現すればよいでしょうか。
サンプルを書き出してみたのですがDraw関数のところで、ハンドル名を直指定してしまっているため
キャラクタークラスを作っても同じ画像が表示されるようにしか書き出せませんでした。

main関係は省略しています

コード:

//キャラクター定義構造体
typedef struct CharcterData{
	string szName;
	int HitPoint;
	int Move;
}CharData;


//キャラクター仮想クラス
class CharBase : public Task{
protected:
	int nPos_x;//ウインドウ座標
	int nPos_y;//ウインドウ座標
	int nScreenPos_x;//スクリーン座標
	int nScreenPos_y;//スクリーン座標
	int nDirection;
	bool bWalkFlag;
	int nHandle;
public:
	CharBase(){};
	~CharBase(){};
	virtual int Updata() = 0;
	virtual int Draw() = 0;
};

//キャラクタ画像管理クラス
class CharImage : public CharBase{
public:
	static void LoadHandle();
	static int nGraph[9];//子クラスを破棄しても画像を再読み込みしないようにここでstaticにしておく
};

//キャラクタークラス
class Charcter : public CharImage{
private:
	CharData cd;
public:
	Charcter(){};
	Charcter(CharData);
	~Charcter(){};
	int Draw() override;
	int Updata() override;
	static void CharProcedure(Charcter *);
};


//描写関数
int Charcter::Draw(){
	DrawGraph(nPos_x - nScroll_x,nPos_y - nScroll_y,nGraph[0],true);//これだと同じ画像しか表示できない・・どのように多態性をもたせればよいですか・・?
	return 0;
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: インスタンスをリサイクルするのはスマートではないでしょうか?

#7

投稿記事 by softya(ソフト屋) » 12年前

これは、グラフィックハンドル自体を管理するクラスを作成すると言うことですね。
グラフィックハンドルが必要な時は、その管理クラスに対してグラフィックハンドルを要求します。
そうすれば、Charcterなどそれぞれのクラスがグラフィックハンドルの破棄や管理をする必要はなくなります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taketoshi
記事: 222
登録日時: 14年前
住所: 日本国

Re: インスタンスをリサイクルするのはスマートではないでしょうか?

#8

投稿記事 by taketoshi » 12年前

アドバイスありがとうございます。
しばらく理解できなかったのですが、少し考えているうちに頭の中でイメージできるようになりました。

以下のように要所を書き換えて、読み込み前にハンドルを要求する関数をかませました。
多態性を確保する一歩を踏み出せたかと感じています。

これに対して、STLのmapクラスを用いて、キーとペアにしてハンドルを返す関数を組みなおせば
キャラクター構造体に代入した数値から画像ハンドルを引き出せるプログラムが組めると考えています。

コード:

//キャラクタ画像管理クラス
class CharImage : public CharBase{
public:
	static void LoadHandle();
	static int nIshtar[9];
	int *ReturnHandle();
};

//ハンドルを返す。引数にキーを設定するように書き換えればok
int *CharImage::ReturnHandle(){
	return nIshtar;
}

//描写

int Charcter::Draw(){

	int *nHandle = ReturnHandle();

	DrawGraph(nPos_x - nScroll_x,nPos_y - nScroll_y,nHandle[0],true);
	return 0;
}
これで前に進めそうです。ありがとうございます。

閉鎖

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