ページ 1 / 1
複数のオブジェクトの扱い方
Posted: 2011年10月13日(木) 23:24
by popcorn
初めまして、最近C++を始めたばかりです。
早速ですが質問させていただきます。
自機の弾を実装しようとしています。
オブジェクトの配列を先に宣言しておきます。
フラグが立っていないオブジェクトを探します。←ここの方法が分からないです。
for(i=0;i<最大数;i++){
if(obj.flag == 0) ~~~
みたいにできれば一番楽なのですが、当然メンバ変数にアクセスできるわけもなく...
じゃあメンバ関数に初期化する関数を入れれば、アクセスできるぞ!と考えましたが、for(...)と併用できそうにありません...
もうflagをpublicにしてしまえばいいのでは?と考えると、それではクラスを使う意味が無くなります。
newを使うのかと考えても、どのみち実装方法がいまいち分かりません。
つまり、配列全体を調べることができ、なおかつ個々のインスタンスにアクセスできる関数をどうやって作ればいいのでしょうかということです。
皆さんはどのように自機の弾を実装していますか?という質問と同じだと思いますが...
よろしくお願いします。
Re: 複数のオブジェクトの扱い方
Posted: 2011年10月13日(木) 23:34
by ISLe
こういうことができれば良いのでしょうか。
コード:
class Foo {
int flag; // 外部からアクセスできない
public:
bool isAlive() { return flag != 0; }
} foo[10];
int main()
{
for (int i=0; i<10; i++) {
if (!foo[i].isAlive()) {
// フラグが立ってないオブジェクト
}
}
return 0;
}
popcorn さんが書きました:皆さんはどのように自機の弾を実装していますか?という質問と同じだと思いますが...
ちゃんと作るときはリストで管理します。
Re: 複数のオブジェクトの扱い方
Posted: 2011年10月14日(金) 00:06
by popcorn
ISLeさん、回答ありがとうございます。
getter,setterの手がありましたね...
今はフラグの確認だけなので大丈夫ですが、実際はこれにx,yもしかしたらv,rad,color,...などが追加されていくと思います。
禁句だとは思いますが、これ全部にgetter,setterをつけていたら正直面倒ではありませんか?
というより、このgetter,setterはオブジェクト指向として正しいのでしょうか?
Re: 複数のオブジェクトの扱い方
Posted: 2011年10月14日(金) 00:57
by tk-xleader
不必要なものにGetter/Setterをつけるのはまずいでしょうけど、メンバ隠蔽・アクセッサメソッド提供はオブジェクト指向なら普通だとは思います。
Getter/Setterはどちらか片方だけを提供するというのもあります。
Re: 複数のオブジェクトの扱い方
Posted: 2011年10月14日(金) 01:37
by popcorn
tkmakwins15さん、返信ありがとうございます。
アクセッサがオブジェクト指向で普通に使われるものということなので安心しました。
Re: 複数のオブジェクトの扱い方
Posted: 2011年10月14日(金) 02:27
by ISLe
popcorn さんが書きました:今はフラグの確認だけなので大丈夫ですが、実際はこれにx,yもしかしたらv,rad,color,...などが追加されていくと思います。
禁句だとは思いますが、これ全部にgetter,setterをつけていたら正直面倒ではありませんか?
メンバ変数ひとつひとつに対応するGetter/Setterを作るようなことはほとんどありませんよ。
x,yを変更するのは、おそらくmove関数やmoveTo関数といったものになるでしょう。
先の回答に書いたコードでメンバ関数の名前はisAliveにしました。
isAlive関数は「生きているか」を判定するための関数と想定しました。
クラス内部の実装が変わっても、isAliveの意味が変わらなければ呼び出し側のコードを変える必要もないわけです。
Re: 複数のオブジェクトの扱い方
Posted: 2011年10月14日(金) 16:45
by popcorn
ISLeさん、再び返信ありがとうございます。
質問の主旨が変わりそうな気がしますが、一応延長線上にあると思いますのでこのまま続けますね。
確かに移動にはMove()、描画にはDraw()を使い、メンバ変数にアクセスします。
しかし、今回は配列全体をfor(...)で調べる関数をメンバ関数に入れることができなかったため、Getterを使って変数にアクセスしました。
今回のisAlive関数に、フラグが立っていなければフラグを立てて、座標の設定をする、という機能を付け加えたい場合を考えると、x,yのSetterを準備する必要がある気がするのですが、間違っているのでしょうか。
もしくは、どのクラスにも属さない、配列の空き番号をisAlive関数を通して返してくれる関数を準備して、その要素番号を使ってメンバ関数obj.Init(){x,yを設定する}を呼び出す、というような方法を使うのでしょうか。
解決しているのに申し訳ないです。よろしくお願いします。
Re: 複数のオブジェクトの扱い方
Posted: 2011年10月14日(金) 17:31
by ISLe
弾オブジェクトは配列の個々の要素ですから、配列からフラグの立ってない個々の要素を横断して探すのは弾オブジェクトの仕事の範疇を超えます。
それは、弾オブジェクトを総括して管理する、いわゆる、弾オブジェクトマネージャー、が請け負う仕事になります。
弾オブジェクトマネージャークラスに、初期化された弾オブジェクトを返すメソッドを実装します。
弾オブジェクトマネージャークラスを隠蔽化することで、弾オブジェクトのバッファは配列でもリストでもかまわないし、いつでも変更できます。
isAlive関数で弾オブジェクトの生存を確認する方法だと、弾オブジェクトに初期化用の公開メソッドを用意して、それを使って座標などをセットする形になります。
弾オブジェクトマネージャーがバッファの要素ごとの使用・未使用を管理する方法もあります。
配置new構文で弾オブジェクトのコンストラクタ・デストラクタを使うようにするとC++言語のコード的に意味が分かりやすくなるかもしれません。