ゲームのクラス設計について
ゲームのクラス設計について
前回は管理クラスとオブジェクト指向について質問をしました。
今回は抱合と継承について質問させていただきたいと思います。
話を単純にするため、今回はSTGにおいて基本的な動作である
自機が、キーを押している間、一定の(時間)間隔をあけながら弾を発射する。
というものを考えたいと思います。
僕が思ったことが、自機は弾を持っているのだから、自機クラスと弾クラスは抱合関係にあるな、というです。
弾クラスのインスタンスの配列が自機クラスに含まれている状態です。
しかし、どうも自機クラスと弾クラスは別物という設計が多い気がします。自機も弾も敵も移動する物体だから、移動物体クラスをつくって、そこから継承しましょう。こんな感じのものが多いと思います。
今回はコード云々よりも、クラス設計についてお聞きしたいと思います。
みなさんは、自機と弾を抱合関係にしますか、しませんか?
しない場合は、設計方法を簡単にでいいので説明していただけるとありがたいです。
なにかしら、自機と弾をつなぐものがあるはずなので、そこを説明してくださると助かります。そのままでは自機の座標を弾に伝えることができないと思います。
よろしくお願いします。
今回は抱合と継承について質問させていただきたいと思います。
話を単純にするため、今回はSTGにおいて基本的な動作である
自機が、キーを押している間、一定の(時間)間隔をあけながら弾を発射する。
というものを考えたいと思います。
僕が思ったことが、自機は弾を持っているのだから、自機クラスと弾クラスは抱合関係にあるな、というです。
弾クラスのインスタンスの配列が自機クラスに含まれている状態です。
しかし、どうも自機クラスと弾クラスは別物という設計が多い気がします。自機も弾も敵も移動する物体だから、移動物体クラスをつくって、そこから継承しましょう。こんな感じのものが多いと思います。
今回はコード云々よりも、クラス設計についてお聞きしたいと思います。
みなさんは、自機と弾を抱合関係にしますか、しませんか?
しない場合は、設計方法を簡単にでいいので説明していただけるとありがたいです。
なにかしら、自機と弾をつなぐものがあるはずなので、そこを説明してくださると助かります。そのままでは自機の座標を弾に伝えることができないと思います。
よろしくお願いします。
Re: ゲームのクラス設計について
今、学校でシューティングゲームを作っていますが、自機の中に弾に関する処理とかを入れたらすごく先生に怒られました。
普通、どんなシューティングゲームでもキャラクターと弾に関する物は別で作るべきであるといわれて。
弾はどのキャラクターにも属さない、独立したオブジェクトらしいです。(もちろん敵の弾か自機の弾かは区別しなければならないですが)
もし、プレイヤーの中に弾に関するものを作ってしまうとキャラクターが死んだとき、弾も同時に消滅してしまう仕様になっていまいます。(まぁそういうゲームもありかもしれませんが)
それを防ぐために色々していくうちにぐちゃぐちゃなプログラムが出来上がり・・・という負の連鎖。自分もやらかしました。
設計の仕方としては、自機クラス内に攻撃時の命令(攻撃ボタンが押されたなどした時の攻撃フラグや初期発射座標など)を出すメソッドを用意して、別に作った弾に関するクラスに投げます。そして自機とは”まったく別の処理として”初期化や更新や描画の処理をさせます。
そうすることで弾を発射したキャラクターが死んでも弾自体は残ったままにすることができるということだそうです。
半分うろ覚えですが。
今現在自分が作った自機と弾に関するプログラムを添付させてもらいます。
いろいろ汚くて残念な作りですが。
参考になったら幸いです。
これ自体プレイヤーがパワーアップすることで弾幕が強化される全方向型のシューティングゲーム用のプログラムです。
ちなみにこれを先生に見せたら苦笑いされました。(いろいろ汚くて)
あと、追記ですがプログラムに絶対的な答えなんてないです。ちゃんと動けばいいんです。そのための組みかたなんていっぱいあります。それこそ私のように考えなら組んでぐちゃぐちゃになったなった酷いプログラムからプロの方が組むようなすっきりとしたプログラムまで。
普通、どんなシューティングゲームでもキャラクターと弾に関する物は別で作るべきであるといわれて。
弾はどのキャラクターにも属さない、独立したオブジェクトらしいです。(もちろん敵の弾か自機の弾かは区別しなければならないですが)
もし、プレイヤーの中に弾に関するものを作ってしまうとキャラクターが死んだとき、弾も同時に消滅してしまう仕様になっていまいます。(まぁそういうゲームもありかもしれませんが)
それを防ぐために色々していくうちにぐちゃぐちゃなプログラムが出来上がり・・・という負の連鎖。自分もやらかしました。
設計の仕方としては、自機クラス内に攻撃時の命令(攻撃ボタンが押されたなどした時の攻撃フラグや初期発射座標など)を出すメソッドを用意して、別に作った弾に関するクラスに投げます。そして自機とは”まったく別の処理として”初期化や更新や描画の処理をさせます。
そうすることで弾を発射したキャラクターが死んでも弾自体は残ったままにすることができるということだそうです。
半分うろ覚えですが。
今現在自分が作った自機と弾に関するプログラムを添付させてもらいます。
いろいろ汚くて残念な作りですが。
参考になったら幸いです。
これ自体プレイヤーがパワーアップすることで弾幕が強化される全方向型のシューティングゲーム用のプログラムです。
ちなみにこれを先生に見せたら苦笑いされました。(いろいろ汚くて)
あと、追記ですがプログラムに絶対的な答えなんてないです。ちゃんと動けばいいんです。そのための組みかたなんていっぱいあります。それこそ私のように考えなら組んでぐちゃぐちゃになったなった酷いプログラムからプロの方が組むようなすっきりとしたプログラムまで。
- 添付ファイル
-
CPlayer.cpp
- (16.98 KiB) ダウンロード数: 416 回
-
CPlayer.h
- (3.38 KiB) ダウンロード数: 298 回
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: ゲームのクラス設計について
TOMYさん、返信ありがとうございます。
言われてみればその通りですね。敵が死んだらその瞬間に、その敵が出した弾が消滅することになりますね。
やはり、機体と弾は分離していないとまずそうですね...
そして、コード読ませていただきました。
自機クラスの中に、InstructionStrというものがあります。これが弾に関するクラスですが、
いわゆる生産クラスというものでしょうか。
このメソッドで、弾の生成に必要な情報(初期座標、初期角度など?)をあたえているのだと思います。
これだけですと、まだ弾は出てこないと思います。
おそらく、弾クラスのインスタンスから空いているところを探して、そこに先ほどの初期情報を投げる、という工程が入ると思います。これは管理クラスの役割ですかね。
自機クラスが弾クラスを持つのは問題なので、自機クラスの中に弾生産クラスを含めると自然かなと思いますが、弾管理クラスはどのように関連付けるべきでしょうか?
個人的には、弾管理クラスが弾生産クラスを持っていて、弾生産クラスが自機クラスと接点がある、という方がわかりやすいのですが...こちらの場合ですと、じゃあどうやって弾生産クラスに自機クラスの情報を与えるかということになります。
簡単にまとめますと、自機クラスと弾管理クラス、弾生産クラス、弾クラスの関係です。
よろしくお願いします。
言われてみればその通りですね。敵が死んだらその瞬間に、その敵が出した弾が消滅することになりますね。
やはり、機体と弾は分離していないとまずそうですね...
そして、コード読ませていただきました。
自機クラスの中に、InstructionStrというものがあります。これが弾に関するクラスですが、
いわゆる生産クラスというものでしょうか。
このメソッドで、弾の生成に必要な情報(初期座標、初期角度など?)をあたえているのだと思います。
これだけですと、まだ弾は出てこないと思います。
おそらく、弾クラスのインスタンスから空いているところを探して、そこに先ほどの初期情報を投げる、という工程が入ると思います。これは管理クラスの役割ですかね。
自機クラスが弾クラスを持つのは問題なので、自機クラスの中に弾生産クラスを含めると自然かなと思いますが、弾管理クラスはどのように関連付けるべきでしょうか?
個人的には、弾管理クラスが弾生産クラスを持っていて、弾生産クラスが自機クラスと接点がある、という方がわかりやすいのですが...こちらの場合ですと、じゃあどうやって弾生産クラスに自機クラスの情報を与えるかということになります。
簡単にまとめますと、自機クラスと弾管理クラス、弾生産クラス、弾クラスの関係です。
よろしくお願いします。
Re: ゲームのクラス設計について
InstructionStrメソッドは直訳すると命令関数です。外部に攻撃するから必要最低限の情報を吐き出させるためのものです。タンタル さんが書きました:自機クラスの中に、InstructionStrというものがあります。これが弾に関するクラスですが、
いわゆる生産クラスというものでしょうか。
このメソッドで、弾の生成に必要な情報(初期座標、初期角度など?)をあたえているのだと思います。
これを弾クラスのBulletInitで受け取り、その時に弾に必要な初期設定をします。
本当は必要な時に必要な個数だけ動的にメモリを確保したかったんですけど、時間無いうえ、ぐちゃりそうだったので断念しています。(チーム制作なので)
それと、実際の使い方を記述したファイルを上げていませんでしたね。私の不注意でした。
実際に使っている部分を上げますが。今からあげるファイルは”動ければいい”程度のものなので(本当はほかのみんなのプログラムがそろった時点で説明しながら統合する予定の為)汚かったり、コーティングルールを無視してたり、注釈文が抜けてたりします。ご了承ください
- 添付ファイル
-
GameMain.cpp
- (5.89 KiB) ダウンロード数: 242 回
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: ゲームのクラス設計について
まず、抱合ってなんでしょうか?
もしかすると、包含(ほうがん)でしょうか?
包含だという前提でお話します。
包含とはhas-a関係と呼ばれ、「AはBを保持している」という事になります。
今回タンタルさんは、「弾は自機が保持している」というのは正しい設計か、というお話だと解釈します。
正しい設計か、それはタンタルさんが決めることですが、私は絶対にしません。
包含というのは、OOPにおいて「最も依存関係の強い設計」であることをよく理解してください。
TOMYさんも指摘していますように、has-aの場合、自機が死ねば弾も死ぬことになります。要は、運命共同体です。
さて、ここでこの設計は、保守性があり、拡張しやすい設計でしょうか?
これは、完全にNOかはそれぞれですが、私はNOだとおもいます。
そもそも包含ということはOOPにおける多態化を使うことができません。
自機が曲がる弾や増える弾、様々な弾を扱えるように柔軟な設計をするのならば、包含ではなく関連にします。
包含と関連の違いは、包含がインスタンスを保持するのに対し、関連はインスタンスのポインタを保持します。
こうした時点で、インスタンスの寿命は調整できますし、弾は多態化でどんな弾でも扱えます。
これが意味的に正しいのかどうかですが、そもそも包含による「自機は弾を保持している」は正しいでしょうか?
自機というものに弾が含まれていて、弾と自機が運命共同体・・・これは依存性が強すぎません?
そうではなく、「自機は弾を知っている(関連:ポインタの保持)」でよいのです。それ以上、深い関係になる必要性があるでしょうか。
オブジェクト指向において、「抽象化」という概念はとても重要です。できる限りオブジェクト間のやり取りは抽象的であるべきなのです。
オブジェクト同士の関係というのはいろいろありますが、注目すべきは「依存性」です。
関連を紹介しましたが自機が弾という存在を知る必要すらなくすることもできます。
依存性を高めるとしたら、もう仕様変更も何もなく、拡張することもなく、ガッチガチのコードにどうしてもしたいときのみです。
依存性の高いコードほど、拡張しにくいものはありません。これは、OOPの設計としては間違いでしょう。
もしかすると、包含(ほうがん)でしょうか?
包含だという前提でお話します。
包含とはhas-a関係と呼ばれ、「AはBを保持している」という事になります。
今回タンタルさんは、「弾は自機が保持している」というのは正しい設計か、というお話だと解釈します。
正しい設計か、それはタンタルさんが決めることですが、私は絶対にしません。
包含というのは、OOPにおいて「最も依存関係の強い設計」であることをよく理解してください。
TOMYさんも指摘していますように、has-aの場合、自機が死ねば弾も死ぬことになります。要は、運命共同体です。
さて、ここでこの設計は、保守性があり、拡張しやすい設計でしょうか?
これは、完全にNOかはそれぞれですが、私はNOだとおもいます。
そもそも包含ということはOOPにおける多態化を使うことができません。
自機が曲がる弾や増える弾、様々な弾を扱えるように柔軟な設計をするのならば、包含ではなく関連にします。
包含と関連の違いは、包含がインスタンスを保持するのに対し、関連はインスタンスのポインタを保持します。
こうした時点で、インスタンスの寿命は調整できますし、弾は多態化でどんな弾でも扱えます。
これが意味的に正しいのかどうかですが、そもそも包含による「自機は弾を保持している」は正しいでしょうか?
自機というものに弾が含まれていて、弾と自機が運命共同体・・・これは依存性が強すぎません?
そうではなく、「自機は弾を知っている(関連:ポインタの保持)」でよいのです。それ以上、深い関係になる必要性があるでしょうか。
オブジェクト指向において、「抽象化」という概念はとても重要です。できる限りオブジェクト間のやり取りは抽象的であるべきなのです。
オブジェクト同士の関係というのはいろいろありますが、注目すべきは「依存性」です。
関連を紹介しましたが自機が弾という存在を知る必要すらなくすることもできます。
依存性を高めるとしたら、もう仕様変更も何もなく、拡張することもなく、ガッチガチのコードにどうしてもしたいときのみです。
依存性の高いコードほど、拡張しにくいものはありません。これは、OOPの設計としては間違いでしょう。
オフトピック
もちろん、包含が完全に間違ってるかはその時次第で、仕様次第です。
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
: ? Is the は :
✜ order C++? ✜
: す + 注 :
¦ か + 文 ¦
: ? Is the は :
✜ order C++? ✜
糸冬
――――――――
制作・著作 NHK
――――――――
制作・著作 NHK
Re: ゲームのクラス設計について
上記について記述忘れてましたので追記です。タンタル さんが書きました:自機クラスと弾管理クラス、弾生産クラス、弾クラスの関係です。
よろしくお願いします。
私の場合は、自機クラスと自機の弾クラスの二つだけです。
弾の生産と管理など、弾に関すること全部、自機の弾クラスでしており、自機クラスは移動の処理と自機の描画、攻撃時の命令のみしてそれぞれが極力干渉することの無いように分け隔てています。
百聞は一見にしかず。うんちくだけを頭にぶち込む前に実際に実験した方がいいよ。
書籍とか経験談とか見て知識をつけるのも大事だけど。
書籍とか経験談とか見て知識をつけるのも大事だけど。
Re: ゲームのクラス設計について
わたしはしません。タンタル さんが書きました:みなさんは、自機と弾を抱合関係にしますか、しませんか?
しない場合は、設計方法を簡単にでいいので説明していただけるとありがたいです。
なにかしら、自機と弾をつなぐものがあるはずなので、そこを説明してくださると助かります。そのままでは自機の座標を弾に伝えることができないと思います。
自機が弾の発生をリクエストするときに自機の座標を渡して、弾が自分で自分の初期位置を設定し、その後も弾が自分で自分の座標を計算します。
弾は自機の相対的な位置にあるのではなく、独自に座標を持って移動します。
自機と自機の周りを移動するオプションの関係でも、包含関係にはしません。
オプションを発生させるときに自機を参照する情報を渡して、オプションが自機の座標を参照し、自分で自分の座標を計算します。
弾管理クラスが弾生産『メソッド』を持てば良いのではないでしょうか。
わたしには弾生産クラスというものがどんなものになるのか想像できません。
Re: ゲームのクラス設計について
TOMYさん、新月の獅子さん、ISLeさん、返信ありがとうございます。
包含ですね、素で勘違いしていました。ご指摘ありがとうございます。
時間がなかったため、お礼が遅れてしまいました。すみませんでした。
とりあえず、TOMYさんに頂いたコードから、自機のインスタンスを引数にすることで、自機と弾の座標のやり取りが解決するなと思います。なんとなく雰囲気はつかめそうです、ありがとうございます。
皆様の回答から、包含関係は間違いと結論付けました。
新月の獅子さんが説明してくださった、関連という関係で考えていきたいと思います。
簡単に調べてみて、包含はクラス内にクラスが直接入るのに対し、関連はクラス内の関数にクラスが入るものかなと考えました。実用性のある具体例が見当たらず、いまいち理解しきれていませんが...
ISLeさん、メソッドでいいとのご意見ありがとうございます。言われてみればその通りですね。これは自機クラスに含めてしまえばいいですね。これで、自機クラス、弾クラス、弾管理クラスのやりとりになります。
ところでなのですが、自機クラスと関連付けるのは弾クラス、弾管理クラスどちらがいいのでしょうか...
弾管理クラスと関連付けたほうがやりやすそうな気がするのですが、普通に考えれば関連あるのは自機と弾のはずです。
いまさらですが、この弾管理クラスって何なのでしょうか...もしかして、自機管理クラスも必要なのではないですか?
下手したら管理クラスを管理するクラスなんていうのも必要なのでは、などと考えてしまいます。
前回、弾の配列全体を調べるために弾管理クラスを作りましたが、配列があるからとかそんな理由だけで管理クラスの要不要が決まるのでしょうか。
質問内容がころころと変わってしまい申し訳ありません。ご迷惑おかけしますが、よろしくお願いします。
包含ですね、素で勘違いしていました。ご指摘ありがとうございます。
時間がなかったため、お礼が遅れてしまいました。すみませんでした。
とりあえず、TOMYさんに頂いたコードから、自機のインスタンスを引数にすることで、自機と弾の座標のやり取りが解決するなと思います。なんとなく雰囲気はつかめそうです、ありがとうございます。
皆様の回答から、包含関係は間違いと結論付けました。
新月の獅子さんが説明してくださった、関連という関係で考えていきたいと思います。
簡単に調べてみて、包含はクラス内にクラスが直接入るのに対し、関連はクラス内の関数にクラスが入るものかなと考えました。実用性のある具体例が見当たらず、いまいち理解しきれていませんが...
ISLeさん、メソッドでいいとのご意見ありがとうございます。言われてみればその通りですね。これは自機クラスに含めてしまえばいいですね。これで、自機クラス、弾クラス、弾管理クラスのやりとりになります。
ところでなのですが、自機クラスと関連付けるのは弾クラス、弾管理クラスどちらがいいのでしょうか...
弾管理クラスと関連付けたほうがやりやすそうな気がするのですが、普通に考えれば関連あるのは自機と弾のはずです。
いまさらですが、この弾管理クラスって何なのでしょうか...もしかして、自機管理クラスも必要なのではないですか?
下手したら管理クラスを管理するクラスなんていうのも必要なのでは、などと考えてしまいます。
前回、弾の配列全体を調べるために弾管理クラスを作りましたが、配列があるからとかそんな理由だけで管理クラスの要不要が決まるのでしょうか。
質問内容がころころと変わってしまい申し訳ありません。ご迷惑おかけしますが、よろしくお願いします。
Re: ゲームのクラス設計について
わたしなら自機クラスには含めません。タンタル さんが書きました:ISLeさん、メソッドでいいとのご意見ありがとうございます。言われてみればその通りですね。これは自機クラスに含めてしまえばいいですね。これで、自機クラス、弾クラス、弾管理クラスのやりとりになります。
コンテキストを介して(あるいはグローバルに)、弾管理クラスに弾の生成をリクエストするように実装します。
上に書いたように、自機クラスと、弾クラス/弾管理クラスは関連を持ちません。タンタル さんが書きました:ところでなのですが、自機クラスと関連付けるのは弾クラス、弾管理クラスどちらがいいのでしょうか...
弾管理クラスと関連付けたほうがやりやすそうな気がするのですが、普通に考えれば関連あるのは自機と弾のはずです。
いまさらですが、この弾管理クラスって何なのでしょうか...もしかして、自機管理クラスも必要なのではないですか?
下手したら管理クラスを管理するクラスなんていうのも必要なのでは、などと考えてしまいます。
自機管理クラスに当たるのは、いわゆるタスク管理クラスです。
もちろん弾クラスもタスクです。
弾管理クラスは弾タスクを専門に管理するクラスです。
以前の質問で自機と弾は別管理したいようだったので、自機と弾を明示的に区別しました。
そのため弾を専門に管理するクラスを提案しました。
汎用のタスク管理クラスを使えば、弾管理クラスは必要なく、生成した弾インスタンスをタスク管理クラスに登録して自機と同列に処理することができます。
そのためにはタスクの多態性を定義しないといけないですが。
弾の配列が、自分で自分の使用状況を調べるというのがオブジェクト指向の基本だと思います。タンタル さんが書きました:前回、弾の配列全体を調べるために弾管理クラスを作りましたが、配列があるからとかそんな理由だけで管理クラスの要不要が決まるのでしょうか。
最後に編集したユーザー ISLe on 2012年9月27日(木) 16:42 [ 編集 1 回目 ]
Re: ゲームのクラス設計について
関連は、インスタンスのポインタを保持すると説明しました。関連はクラス内の関数にクラスが入るものかなと考えました。
タンタルさんのポインタについての理解の程がわからないので聞きますが、このAとBのクラス、何が違うかわかりますか?
「オブジェクト指向的な設計をするならどうすればいいか」というお話だと解釈します。ところでなのですが、自機クラスと関連付けるのは弾クラス、弾管理クラスどちらがいいのでしょうか...
弾管理クラスと関連付けたほうがやりやすそうな気がするのですが、普通に考えれば関連あるのは自機と弾のはずです。
いまさらですが、この弾管理クラスって何なのでしょうか...もしかして、自機管理クラスも必要なのではないですか?
下手したら管理クラスを管理するクラスなんていうのも必要なのでは、などと考えてしまいます。
前回、弾の配列全体を調べるために弾管理クラスを作りましたが、配列があるからとかそんな理由だけで管理クラスの要不要が決まるのでしょうか。
それこそ、ここからが設計の本番なわけです。それで私達が具体的な見解を出してもいいですが、それぞれのレベルによって回答は違うでしょうし、設計・仕様の目的などによっても変わってきます。そして、プロの方が美しく書いたコードはまだ良さがわからないでしょう。
ただし、一つ言うなら、結局のところ、前回の質問での返信や今回の質問への返信とオブジェクト指向的プログラミングの基本は変わらないということです。
たとえば自機が弾が直接弾を管理していたらどうなるのか、管理クラスに任せるとしてどのようなアクセッサを用意するか、自機管理クラスが必要だと思うなら自機管理クラスを作ってみるのも良いですし、管理クラスの管理クラスの管理クラスをつくるのは正しいのか考えてみましょう。
ただし、これはそろそろ貴方自身でもう少し判断してみましょう。
別に投げるのではなく、そろそろ判断できるのではないでしょうか。
先程も言ったように基礎は変わりません。
自機が弾を管理していたら依存性はどうなるのか、依存性を減らすにはどうしたら良いのか。管理クラスと自機クラスではなく、管理クラスを持った、自機と関わるのが正しいオブジェクトは無いだろうか。自機管理クラスが何をする型なのか、管理クラスの管理クラスの管理クラスは、本当に管理しやすいのか。
どうすれば柔軟で保守性を持った、よいコードが書けるのか、前回皆さんにもらったアドバイスを含め、そろそろこの「弾の管理」というものについて自分なりに設計できると思います。
もしコードを作ったらみなさんちゃんと設計について指摘をくださるでしょうから、貴方なりに考えて一度コードを書いて投稿してみてください。
質問するのは良いことですが、結局は書いて学ぶことのほうが遥かに多いのです。それと、ただ「動けばイイ」コードではなく、頭を捻って作ってみてください。何度もリファクタリングし、書きなおす事が大事です。時間をかけて作ってみてください。他の方のくださったアドバイスを考慮に含めて、書いてみないと実力にはなりませんよ。
※ちなみにタンタルさんが多態化について知ってるのかわからないのですが、わからないならウェブで調べたり、ここで質問したり、以前私が他の方に書いた返信(これ)を参考にするなどしてください。
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
: ? Is the は :
✜ order C++? ✜
: す + 注 :
¦ か + 文 ¦
: ? Is the は :
✜ order C++? ✜
糸冬
――――――――
制作・著作 NHK
――――――――
制作・著作 NHK
Re: ゲームのクラス設計について
ISLeさん、 新月の獅子さん、返信ありがとうございます。
何となくわかったような、わからないような...少しもやもやした感じがします。
具体的に何が理解できてないかはわからないので何も言えないですが...
新月の獅子さんの例にある、クラスA,Bの違いですが、機能的な違いは分からないです。
ポインタの使い道や、使うと何がいいのかというところは分かっていません。値渡し、参照渡しくらいしか理解していないです。
なので、絶対使わないようにしています。
とりあえず、自機の座標を弾に与える方法についての目途がたったと思うので、もう一度考えてみます。
次は何かしらコードを乗せられるよう頑張ってみます。
ありがとうございました。
何となくわかったような、わからないような...少しもやもやした感じがします。
具体的に何が理解できてないかはわからないので何も言えないですが...
新月の獅子さんの例にある、クラスA,Bの違いですが、機能的な違いは分からないです。
ポインタの使い道や、使うと何がいいのかというところは分かっていません。値渡し、参照渡しくらいしか理解していないです。
なので、絶対使わないようにしています。
とりあえず、自機の座標を弾に与える方法についての目途がたったと思うので、もう一度考えてみます。
次は何かしらコードを乗せられるよう頑張ってみます。
ありがとうございました。
Re: ゲームのクラス設計について
これはあまりよろしくないですね。ポインタを理解していないのではオブジェクト指向以前の問題でよくありません。タンタル さんが書きました:ISLeさん、 新月の獅子さん、返信ありがとうございます。
何となくわかったような、わからないような...少しもやもやした感じがします。
具体的に何が理解できてないかはわからないので何も言えないですが...
新月の獅子さんの例にある、クラスA,Bの違いですが、機能的な違いは分からないです。
ポインタの使い道や、使うと何がいいのかというところは分かっていません。値渡し、参照渡しくらいしか理解していないです。
なので、絶対使わないようにしています。
とりあえず、自機の座標を弾に与える方法についての目途がたったと思うので、もう一度考えてみます。
次は何かしらコードを乗せられるよう頑張ってみます。
ありがとうございました。
オブジェクト指向は実際はしなくともよいもので、あくまでも設計思想の一つです。それは言語の機能をよく理解していないとできるはずがありません。多態化というオブジェクト指向的テクニックでは、ポインタも必要になりますし、もっとオブジェクト指向を理解しようと思ったら、ポインタについて勉強しないと不可能でしょう。
ポインタについて全て語るのはさすがに骨が折れるので、例えばどのような場面でポインタを使うか、例を挙げてみます。(関数ポインタとかの話はしてません)
このコードですが、全く意味が違います。
そもそも、Object型とObject*型はまったく別物です。
Object型はそのとおり、Object型の大きさのインスタンスの入った変数です。その一方で、Object*型は、Object型のインスタンスがあるメモリアドレスを入れる為の変数です。
変数、関数、インスタンス、全てはメモリ上に存在していて、当然アドレスと呼ばれる、住所のようなものを持っています。
Bは、住所を知っているだけで、Object型のインスタンスを持っていません。これは、とてつもなく大きな違いです。
例えば、Object型が120byteのとても大きなインスタンスだとしましょう。そうすると、A型は120byteよりさらに大きくなります。なぜなら、中にObject型を保持しているからです。
一方、Object*型はあくまでもアドレスです。アドレス型は、実はどのアドレス型(Object*型もA*型もB*型も)も、実際は4byteです(保証はされていない)。なぜならメモリアドレスだけあればよいから。そうすると、AとBではインスタンスのサイズから大きな差が生まれます。当然実行速度にも積み重なれば大きな差がでます。特にコピーなどのコストが大きくなります。
また、関数で引数を値渡しするかの話でもポインタの方が効率が良くなる場合があります。
A test( A a ){
/// aをいじり、最後にいじり終わったaを戻り値で返す
/// この時、引数として受け取る時点で一回コピーが、戻り値を代入する時にもう一回と、二回コピーが起きる
}
void test2( A& a ) //< 今回の話的には「A* a」でも良いが、これは値渡しなので参照を渡すべき。今回とは少し話が違うので説明はカット
{
/// aをいじる際、もらったのは住所なので、コピーは発生していない
/// 戻り値で返す必要もない
}
void test3()
{
A instans; //< A型のインスタンス
instans = test1( instans ); //< 引数で渡す際に一回目のコピー
/// ↑「=」の代入で二回目のコピー
test2( instans ); //< コピーは起きない
}
また、Object*は住所ですから、そこにどんなObject型が住んでいても構わないのです。多態化についてまだ知らないかもしれないので詳細は言いませんが、Object型の振る舞いさえ持っていれば派生クラスもそこに住ませることができます。これは、プログラムにおいて柔軟な設計の鍵になります。
ここでもう一度言うと、ポインタを保持するのとインスタンスを保持するのとでは依存性が全く違います。
(A)一緒に住むのと(B)住所を知っているのとで、もし自分の家が燃えて自分が死んでしまったら、(A)一緒に住んでいるものも死にますし(B)住所を知っているだけなら対岸の火事です。
※当然ですがAが正しい場合もあります。「依存性が違う」ということです。
「ポインタ」が苦手な人がなぜか多いようです。ポインタは実際は理解せずともプログラムは書けますが、メモリを操作しないのであればC系統の言語で書く必要はほとんどありません。メモリを低水準なレベルで操作できることは、単純な処理の効率化だけでなく、多彩なテクニック(関数ポインタや多態化など)に必要不可欠です。
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
: ? Is the は :
✜ order C++? ✜
: す + 注 :
¦ か + 文 ¦
: ? Is the は :
✜ order C++? ✜
糸冬
――――――――
制作・著作 NHK
――――――――
制作・著作 NHK