前の節ではメインファイルがごちゃごちゃして、どこで、変数定義して、どこでexternしたのかよくわからなくなってしまいました。
そこで、変数定義やextern宣言の仕方を工夫してみましょう。
ちょっとここで、前章のおさらいしてみます
・(今回の設計の場合) グローバルな変数の定義はメインファイルmain.cppで行う
・他のファイルで参照したい時は、他のファイルではextern宣言する
ということでしたよね。
しかしメインファイルで宣言したり、同じ変数名を他のファイルではexternしたりするのは何だか非効率な気がします。
そこで、同一ヘッダファイルを全てのファイルから呼び出し、そのヘッダファイル内で
どこから呼ばれたのか調べ条件分岐して、適切な宣言をさせてやることが出来れば効率的になります。
ちょっと以下のプログラムを見て下さい。
#ifdef GLOBAL_INSTANCE #define GLOBAL #else #define GLOBAL extern #endif GLOBAL int img;
前半は
「GLOBAL_INSTANCEが定義されていればGLOBALという文字は空白に置き換えられる」
「GLOBAL_INSTANCEが定義されていなければGLOBALという文字はexternに置き換えられる」
という意味です。
そうして
GLOBAL int img;
と書くとどうなるか、そう、externを付けるかつけないか分けることが出来るんです。
main.cppから呼ばれた時は定義しないといけないからexternを付けたくありません。
つまりGLOBAL_INSTANCEを定義してから呼べばいいことになります。
一方他のファイルから呼ばれたときは、externを付けたいです。
つまりGLOBAL_INSTANCEを定義せず、何も書かずに呼べばいいことになります。
ここでメインファイルの一番上を見て下さい。
#define GLOBAL_INSTANCE
#include "../include/GV.h"
を書いてありますね。GLOBAL_INSTANCEを定義してから呼び出しているので、宣言になるのです。
一方他のファイルからは定義されていない状態で呼び出されているので、externが付くのです。
こうして、他のファイルから呼び出せるようになります。
それともう一つ。実装した関数を他のファイルから呼び出したいときも、同様にメインファイルで宣言する必要があります。
エクスターン宣言をすれば実装箇所・呼び出し箇所が上下どちらでもよくなったように、メインファイルで宣言しておけば、
どこで実装してもよく、extern宣言すればどこからでも呼び出せます。
そこで条件わけしたGV.hの中にあるfunction.hに上記同様にGLOBALと書いて宣言してみます。
まぁ見てるだけじゃ解りにくいので、下のように追加して下さい。
--function.h変更-- //graph.cpp //描画メイン GLOBAL void graph_main(); //key.cpp //現在のキー入力処理を行う GLOBAL int GetHitKeyStateAll_2(); //受け取ったキー番号の現在の入力状態を返す GLOBAL int CheckStateKey(unsigned char Handle); //laod.cpp //データのロード GLOBAL void load();
--GV.h変更-- #include "../../../include/DxLib.h" #include "define.h" #ifdef GLOBAL_INSTANCE #define GLOBAL #else #define GLOBAL extern #endif #include "function.h" //関数宣言 //画像用変数宣言部 GLOBAL int img_ch[2][12]; //キャラクタ画像9枚分 X2(変身用) //構造体変数宣言部 GLOBAL ch_t ch; //キャラクタデータ宣言
後は「main.cpp」「graph.cpp」「load.cpp」にある変数の定義部と、extern宣言を全て消してください。
コンパイル実行して、エラーも無く4節と同じ実行結果になればOKです。
今後、グローバル変数を追加したい時はGV.hに追加し、
メインファイルから呼ぶ必要のある他のファイルで宣言した関数はfunction.hファイルに追加していきましょう。
- Remical Soft -