ページ 11

変数や定数の宣言を別ファイルにするには?

Posted: 2011年10月13日(木) 09:55
by 史上最悪のデスペナ
すごく初歩的な質問で申し訳ありません。調べてみたのですが、分からなかったのでこちらで質問させていただきます。

仮に、こんな感じにファイルがあったとします。(DXLibのリファレンスページのコピペ)

main.cpp

コード:

#include "DXLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
{
	int FontHandle ;

	// DXライブラリの初期化
	if( DxLib_Init() == -1 ) return 0 ;


	//  デフォルトのフォントで、サイズ40、太さ3のフォントを作成し
	// 作成したデータの識別番号を変数 FontHandle に保存する
	FontHandle = CreateFontToHandle( NULL , 40 , 3 ) ;

	// 作成したフォントで画面左上に『Hellow!!』と白色の文字列を描画する
	DrawStringToHandle( 0 , 0 , "HELLOW!!" , GetColor( 255 , 255 , 255 ) , FontHandle ) ;

	// 次に標準フォントデータで画面に『OK?』という文字列を描画する
	DrawString( 0 , 50 , "OK?" , GetColor( 255 , 128 , 100 ) ) ; 


	// キー入力を待つ
	WaitKey() ;

	// 作成したフォントデータを削除する
	DeleteFontToHandle( FontHandle ) ;


	// DXライブラリの終了
	DxLib_End() ;

	// ソフトの終了
	return 0 ;
}
この、「int FontHandle;」をmain.cppではなく、別のところに書いてリンクするにはどうしたらいいでしょうか?
ヘッダーファイルに書くとグローバル変数になってよくないという理解をしています。
なので変数.cppに書いてインクルードしたところ「すでに宣言されています」というエラーメッセージが出ました。

変数の宣言が多くなってしまったためmain.cppを見やすくしたいのです。お力をお貸しください

Re: 変数や定数の宣言を別ファイルにするには?

Posted: 2011年10月13日(木) 10:34
by softya(ソフト屋)
int FontHandle;を別のファイルに書く段階でグローバル変数です。ヘッダに書くことがグローバル変数の条件ではありません。

最近こちらのトピックでも話題にしたのですが、
「キャラの構造体管理 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=9356
次のことを理解して変数を使い分けてください。
使う望ましさで言うと ローカルスコープ > ファイルスコープ > グローバルスコープ です。
[変数の寿命]
変数は基本的に{}で示されるブロック内の寿命であるが、staticを付けた場合はプログラム起動から終了までの寿命となり初期化も起動時の一度しか行われない。逆にstaticがないと毎回初期化される。
それと関数外に宣言した場合は、これもプログラム起動から終了までの寿命となる。

[変数のスコープ]
ローカルスコープ:関数内や{ブロック}内のローカル変数として宣言した場合。そのブロック{}内でしか参照できない。
ファイルスコープ:関数外でかつstatic宣言した場合。そのコンパイル単位であるファイル内からしか参照できない。
グローバルスコープ:関数外でかつ、staticを付けなかった場合。extern宣言をすると別cppからでも参照可能になる。
それとバラバラの変数ではなく機能単位の構造体にまとめることも需要です。

Re: 変数や定数の宣言を別ファイルにするには?

Posted: 2011年10月13日(木) 10:59
by 史上最悪のデスペナ
結構頭がこんがらがってしまいました^^;
softya(ソフト屋)さんの講座も拝見させていただいたのですが
構造体をポインタで参照するのはグローバル変数とどう違うのかなどなど・・・・・
もう少し調べて頑張ってみます。
ちなみに、貼っていただいたリンクの内容がほとんど理解できませんでした・・・・

Re: 変数や定数の宣言を別ファイルにするには?

Posted: 2011年10月13日(木) 11:13
by softya(ソフト屋)
グローバル変数が嫌われるのは、値を参照・書き換えるタイミングが適切に設計されていないからグローバル変数にする人が多いからです。
ちゃんとタイミング設計されていればグローバル変数にする必然は殆ど無いはずですので、良く処理を見なおしてください。

最初にサンプルで書かれたFontHandleの件で言えば、例としてstatic int FontHandle; を持ったFontString.cppにCreateFontToHandle()やDrawStringToHandle()のための処理関数を持てば完全にFontString.cpp内にFontHandleを閉じ込められるはずです。これもオブジェクト指向で言うところのカプセル化と同じ考え方ですね。