ページ 11

グローバル変数とローカル変数について

Posted: 2012年2月15日(水) 22:18
by 化猫
現在DXライブラリで1からゲームを作っています。
龍神録からC++を学び始めました。
しかし、これを参考に設計するとグローバル変数が大量に作られてしまうので、自分の今考えている書き方で大丈夫なのか教えていただきたいです。

主に疑問に思っているのがメモリとの関係です。
グローバル変数はプログラムが終了するまでメモリのその領域を保持し続けるようで、龍神録のように画像などを最初に読み込み、終了までメモリに確保し続けるのはメモリを無駄に使っていると思いました。
本来は必要な時に関数内で読み込み、表示させ、関数から抜けたら解放するというのがベストなのでしょうか?
BGMなどもそうです。龍神録でいうfontやcolorなどもローカルにしようと思えば可能ですが、極端な話グローバル変数はない方が良いのでしょうか?

また、逆にグローバル変数で書くべきものがありましたら、例を挙げていただけると幸いです。
宜しくお願い致します。

※龍神録のプログラムが悪いように思われるような書き方で申し訳ありません。 龍神録のプログラムは難しい話を避け、簡単に作れるよう書かれたものです。 今回はそこからステップアップしたいと思い質問しました。

Re: グローバル変数とローカル変数について

Posted: 2012年2月15日(水) 22:34
by みけCAT
化猫 さんが書きました:グローバル変数はプログラムが終了するまでメモリのその領域を保持し続けるようで、龍神録のように画像などを最初に読み込み、終了までメモリに確保し続けるのはメモリを無駄に使っていると思いました。
本来は必要な時に関数内で読み込み、表示させ、関数から抜けたら解放するというのがベストなのでしょうか?
BGMなどもそうです。
今時のパソコンでは、関数を呼ぶたびにいちいちその関数内で画像等を読み込み直す方が、
メモリに保持するより遥かに無駄です。

Re: グローバル変数とローカル変数について

Posted: 2012年2月15日(水) 22:45
by 化猫
回答ありがとうございます。
みけCAT さんが書きました:今時のパソコンでは、関数を呼ぶたびにいちいちその関数内で画像等を読み込み直す方が、
メモリに保持するより遥かに無駄です。
ということは、龍神録のように画像などを読み込むことは問題ない。
なんでもかんでもグローバル変数にせず、関数を使って引き渡す等の工夫をするべきでその他変数をグローバル化して他のファイルから書き換えられるようにすると良くないということでしょうか?

Re: グローバル変数とローカル変数について

Posted: 2012年2月15日(水) 23:47
by softya(ソフト屋)
むやみにロード/アンロードを繰り返すと時間を相当をロスしますので、ステージの切り替えタイミングなどまとめてアンロード/ロードを行ったほうが良いでしょう。
グルーバルな変数は破壊や書き換えのリスクが多いので見える所は局所的な場所に制限した方がより安全になります。
[危険] → → → [安全]
グローバルスコープ(関数外の変数) → ファイルスコープ(staticを付けた関数外の変数) → 関数スコープ(関数内に書いた変数) → ブロックスコープ({}内に書いた変数)

ただ関数スコープやブロックスクープは変数寿命や参照範囲が制限されますので使い所をよく理解して使うことが大事です。
ファイルスコープ変数にして設定/参照関数で外部からの変数へのアクセスを制限・チェックする方法もあります。

Re: グローバル変数とローカル変数について

Posted: 2012年2月15日(水) 23:53
by Dixq (管理人)
仰るように正直龍神録は大きなプログラムの設計には向きませんし、小さな設計であっても、あのように作るべきではないと思います。
とりあえずポインタを使いたくなかったのですが、途中から結局使ってたり意味不明な解説になってます。。。

ゲームの設計については、ゲームプログラミングの館の
http://dixq.net/g/
設計についてよければ参考にして下さい。
グローバル変数について、疑問に思っていらっしゃるようですが、上記解説のように、
モジュールを統括する部分で、限定的に参照可能なstatic変数にすることで安全かつ効率化できます。

C言語で大規模な設計を効率的に行うのは若干難しいですが、上記解説にあるようにモジュールは完全に引数依存で動作するようにし、
その管理部にはモジュール内でしか利用できないグローバル変数を使うなどすることで幾分マシな設計が出来るようになるかと思います。
C言語でクラスモドキの振る舞いもできますが、無理にそんなことをするなら、環境がC++なんですからいっそのことC++で書いた方がいいように思います。

fontやcolorについてですが、colorは単なるintですから、いくら持っていても問題になりません。
しかしfontはかなりのデータを食いますから必要ない時は解放すべきでしょう。
画像も、必要に応じて解放すべきですが、関数を抜けるたびに解放するのはよく無いです。
普通面単位でロード・解放するのが一般的です。
1面、2面等の単位で分割すると良いでしょう。
もちろんメニュー画面やOP、ED等も別で良いと思います。

Re: グローバル変数とローカル変数について

Posted: 2012年2月16日(木) 00:35
by h2so5
そもそもDXライブラリの場合、グローバル変数に画像を読み込んでもグローバル変数に代入されるのは画像のidで
画像データ自体はヒープ領域に展開されますから、画像データの寿命はグローバル変数のそれとは違います。

Re: グローバル変数とローカル変数について

Posted: 2012年2月16日(木) 13:00
by 化猫
なるほど、必要以上の読み込み、解放も無駄だということですね。
まずは必要以上にグローバル変数としている部分がないか見直し、改良していきます。

皆様、回答ありがとうございました。