ページ 1 / 1
構造体のグローバル宣言と使用について
Posted: 2010年2月22日(月) 20:07
by ti
いつもお世話になっています
ゲーム内の数値などをまとまって扱う構造体を共有したく
global.hとglobal.cppと実際に使うcppファイルで宣言しています
---------------global.h-----------------------------
//-----------------------------------------
//キャラデータ構造体
//-----------------------------------------
typedef struct{
int str,agi,Tough,Intelligence,luck,MAXHP,MAXMP,Offens,defens,Ex;//力すばやさ体力運HPMP攻撃力防御力経験値
}st_Details_data;
//2ndキャラ以降の位置情報構造体
typedef struct{
int x,y,img,muki,walking_flag;
st_Details_data ch_data[8];
}st_chdata;
//プロトタイプ宣言
int Load();
-------------------global.cpp------------------------------------------------
int Load(){
st_chdata chdata;
return 0;
}
----------------------chdataを仕様する場所---------------------------
グローバル領域で
st_chdata chdata;
と宣言しています
この状態でビルドするとリンカエラーがでてしまい
chdataを仕様する場所のst_chdata chdataをコメント化すると
定義していないといわれてしまいます
複数の場所で同じ構造体データを共用したい場合
どのように宣言すればいいですか?
よろしくお願いします
Re:構造体のグローバル宣言と使用について
Posted: 2010年2月22日(月) 20:24
by array
エラー報告の場合、エラー情報をコピーして貼り付けていたほうが、的確な回答が得られやすいですよ。
他のファイルにある関数や変数を使用する場合、extern宣言が必要になるのでプログラムだけを見た感じだと
//プロトタイプ宣言
extern int Load();
と追記すれば、コンパイルは成功すると思います。
Re:構造体のグローバル宣言と使用について
Posted: 2010年2月22日(月) 20:40
by ti
arrayさんレスありがとうございます
make cmd.cppのst_chdata chdataをいれると
1>make town.obj : error LNK2005: "struct st_chdata chdata" (?chdata@@3Ust_chdata@@A) は既に make cmd.obj で定義されています。
1>make cmd.obj : error LNK2001: 外部シンボル ""int __cdecl Make_CmdWindow0(void)" (?Make_CmdWindow0@@YAHXZ)" は未解決です。
となります
make cmd.cppのst_chdata chdataをコメント化すると
>.\make cmd.cpp(28) : error C2065: 'chdata' : 定義されていない識別子です。
1>.\make cmd.cpp(28) : error C2228: '.x' の左側はクラス、構造体、共用体でなければなりません
1> 型は ''unknown-type'' です。
1>.\make cmd.cpp(28) : error C2228: '.y' の左側はクラス、構造体、共用体でなければなりません
1> 型は ''unknown-type'' です。
となります
int Load()関数は初期化するために使用しています
Re:構造体のグローバル宣言と使用について
Posted: 2010年2月22日(月) 21:05
by array
ちょっと頭が回らないのですが、
LNK2005のエラーは構造部を多重定義している時に出ます。
town.cppの中にあると思われる
struct st_chdata chdata;
下記に変更
extern struct st_chdata chdata;
extern宣言は違うところで定義してますよ。とコンパイラに教える為に宣言します。
@多分、cmd.cpp で既に定義されていますよ。といわれているエラーだと思います
Re:構造体のグローバル宣言と使用について
Posted: 2010年2月22日(月) 23:08
by ti
LNK2005は直ったのですが
LNK2001が出ています
エラーコードです
1>make cmd.obj : error LNK2001: 外部シンボル ""struct st_chdata chdata" (?chdata@@3Ust_chdata@@A)" は未解決です
ソースファイルあげておきます
typedef struct{
int x,y,img,muki,walking_flag;
st_Details_data ch_data[8];
}st_chdata;
はglobal.cppでのみ定義しています
st_chdataの内容を1箇所で宣言してほぼすべてのcppで使用したい場合どうすればいいですか?
書き方がわるくて何をやりたいのかわかりにくかったとおもいます
ある構造体で定義した変数をすべてのファイルで使用できて
それを常に数値を維持できるようにしたいです
Re:構造体のグローバル宣言と使用について
Posted: 2010年2月23日(火) 09:03
by non
> typedef struct{
> int x,y,img,muki,walking_flag;
> st_Details_data ch_data[8];
>
> }st_chdata;
> はglobal.cppでのみ定義しています
ソースを見ると、global.hで定義されています。
>
> st_chdataの内容を1箇所で宣言してほぼすべてのcppで使用したい場合どうすればいいですか?
1カ所のファイルのみ
st_chdata chdata;
と宣言し、
他のchdataを使いたいファイルでは
extern st_chdata chdata;
と宣言する。
現状では、
実体を宣言しているものがない(すべてがexternになっている)
なお、関数Loadの中で宣言されているchdatは、ローカル変数であり、他のグローバル変数とは
別物です。
Re:構造体のグローバル宣言と使用について
Posted: 2010年2月23日(火) 09:36
by たかぎ
こうした問題を解消するには、次のようにするのが案外よかったりします。
inline st_chdata& refer_chdata()
{
static st_chdata chdata;
return chdata;
}
このインライン関数をglobal.hあたりで定義します。
こうすることのメリットは少なくありません。
・この中にブレークポイントを貼れば、どこからアクセスされているかを追跡できます。
・externを付けるものと付けないものを区別する必要がありません。
・非局所オブジェクトの初期化(および解体)順序に悩まされる心配がなくなります。
ただし、デメリットが無いわけではありません。
最大のデメリットは、マルチスレッド環境の場合、複数のスレッドから同時に初期化される危険性があることですが、必要に応じてDouble-checked Lockingでも使って解消してください(詳しくは説明しきれないので検索してください)。
Re:構造体のグローバル宣言と使用について
Posted: 2010年2月23日(火) 21:25
by ti
nonさんたかぎさん書き込みありがとうござます
インライン関数はまだ自分には難しくてすぐには使えそうにないですね・・・
ある程度余裕できてきたらやってみます
>ソースを見ると、global.hで定義されています。
これはたぶん自分の書き間違えです
関数のプロトタイプ宣言と構造体の定義?はヘッダでするようにしてますので
また質問なのですが
変数や構造体のグローバル使用のときは
一箇所でのみ(グローバル領域で)
st_chdata chdata;
や
int Flg;
と宣言して他ではexternを付けて宣言すればいいのですか?
Re:構造体のグローバル宣言と使用について
Posted: 2010年2月23日(火) 21:54
by たかぎ
> インライン関数はまだ自分には難しくてすぐには使えそうにないですね・・・
食わず嫌いみたいなもんだと思います。

Re:構造体のグローバル宣言と使用について
Posted: 2010年2月23日(火) 21:57
by array
そうです。正確に言えば、実体は1つだけしか存在しません。
しかし、それだと他のファイルから参照できないので、extern宣言を記述する事で参照できるようになります。
Re:構造体のグローバル宣言と使用について
Posted: 2010年2月26日(金) 02:34
by ti
ありがとうございました
無事作成できました
>食わず嫌いみたいなもんだと思います。
すいませんでした