こんばんわ。
プログラミングの設計についてお尋ねしたいことがあります。
敵クラスや弾丸クラス等、同じようなオブジェクトを複数扱うとき
敵や弾丸が消滅したらインスタンスもdeleteするべきなのでしょうか?
パラメータ関係を再度初期化してリサイクルし出現させるって方法はあまりスマートではない気がしています。
このようなプログラムを組むとき、敵や弾丸にそってインスタンスも消滅させ
次に出現するときはインスタンスを作り直すのがよいのか
どちらの方が設計的に理にかなっているのかご指導ください。
インスタンスをリサイクルするのはスマートではないでしょうか?
Re: インスタンスをリサイクルするのはスマートではないでしょうか?
インスタンスを作り直すように設計したほうが簡単だと思います。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: インスタンスをリサイクルするのはスマートではないでしょうか?
私も簡単でバグの減る方はどっちかで考えるべきだと思います。
画像ハンドルを保持している場合は、画像ハンドルは別クラスで管理しましょう。
画像ハンドルを保持している場合は、画像ハンドルは別クラスで管理しましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: インスタンスをリサイクルするのはスマートではないでしょうか?
newでインスタンスを作りなおすと、素直で分かりやすくなるけどnewのせいで遅くなる
インスタンスを再度初期化して使いまわすと、newを使わない分速くなるけど分かりにくくなる
というので悩んでいるのであれば、配置newを検討してみてはいかがでしょうか。
普通のnewを使うときの分かりやすさと、newを使わない速さを両立できるのではと思います。
インスタンスを使いまわすときは、恐らくインスタンスの配列があって、その配列の中から現在使われていないインスタンスを探し、そのインスタンスを再初期化して使うんですよね。
この過程のうち「再初期化」の部分を配置newでやるわけですね。
配置newは、メモリ領域を新たに確保せず、既に存在するメモリ領域にインスタンスを配置します。
普通のnewは、new自身がmallocで確保した領域にコンストラクタを適用するのに対して、配置newは、ユーザーが指定した領域にコンストラクタを適用するものです。
インスタンスを再度初期化して使いまわすと、newを使わない分速くなるけど分かりにくくなる
というので悩んでいるのであれば、配置newを検討してみてはいかがでしょうか。
普通のnewを使うときの分かりやすさと、newを使わない速さを両立できるのではと思います。
インスタンスを使いまわすときは、恐らくインスタンスの配列があって、その配列の中から現在使われていないインスタンスを探し、そのインスタンスを再初期化して使うんですよね。
この過程のうち「再初期化」の部分を配置newでやるわけですね。
配置newは、メモリ領域を新たに確保せず、既に存在するメモリ領域にインスタンスを配置します。
普通のnewは、new自身がmallocで確保した領域にコンストラクタを適用するのに対して、配置newは、ユーザーが指定した領域にコンストラクタを適用するものです。
Re: インスタンスをリサイクルするのはスマートではないでしょうか?
皆さん返信ありがとうございます。
一般的な指針が理解できました。
>>beatleさん
こういった手法もあるんですね。勉強になります。
>インスタンスを使いまわすときは、恐らくインスタンスの配列があって
今までこういった手法でやっていたので、配置newの概念も理解できました。
ありがとうございます。解決とさせていただきます。
一般的な指針が理解できました。
>>beatleさん
こういった手法もあるんですね。勉強になります。
>インスタンスを使いまわすときは、恐らくインスタンスの配列があって
今までこういった手法でやっていたので、配置newの概念も理解できました。
ありがとうございます。解決とさせていただきます。
最後に編集したユーザー taketoshi on 2013年2月26日(火) 21:18 [ 編集 1 回目 ]
Re: インスタンスをリサイクルするのはスマートではないでしょうか?
すいません、ひとつ質問があります
softyaさんの発言に対してなのですが
>画像ハンドルを保持している場合は、画像ハンドルは別クラスで管理しましょう。
これはどのように実現すればよいでしょうか。
サンプルを書き出してみたのですがDraw関数のところで、ハンドル名を直指定してしまっているため
キャラクタークラスを作っても同じ画像が表示されるようにしか書き出せませんでした。
main関係は省略しています
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: インスタンスをリサイクルするのはスマートではないでしょうか?
これは、グラフィックハンドル自体を管理するクラスを作成すると言うことですね。
グラフィックハンドルが必要な時は、その管理クラスに対してグラフィックハンドルを要求します。
そうすれば、Charcterなどそれぞれのクラスがグラフィックハンドルの破棄や管理をする必要はなくなります。
グラフィックハンドルが必要な時は、その管理クラスに対してグラフィックハンドルを要求します。
そうすれば、Charcterなどそれぞれのクラスがグラフィックハンドルの破棄や管理をする必要はなくなります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: インスタンスをリサイクルするのはスマートではないでしょうか?
アドバイスありがとうございます。
しばらく理解できなかったのですが、少し考えているうちに頭の中でイメージできるようになりました。
以下のように要所を書き換えて、読み込み前にハンドルを要求する関数をかませました。
多態性を確保する一歩を踏み出せたかと感じています。
これに対して、STLのmapクラスを用いて、キーとペアにしてハンドルを返す関数を組みなおせば
キャラクター構造体に代入した数値から画像ハンドルを引き出せるプログラムが組めると考えています。
これで前に進めそうです。ありがとうございます。
しばらく理解できなかったのですが、少し考えているうちに頭の中でイメージできるようになりました。
以下のように要所を書き換えて、読み込み前にハンドルを要求する関数をかませました。
多態性を確保する一歩を踏み出せたかと感じています。
これに対して、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;
}