ページ 11

ファイル分割について

Posted: 2013年4月30日(火) 23:57
by てのん
一応新・ゲームプログラミングの館でファイル分割についてみたのですが
いまいち分からなくて・・・ それでも自分なりに考えてコードは書いてみたのですが
やはりなんともいいがたい結果だったのでここに投稿させていただきます

DXライブラリで画像をファイル分割させて表示するだけなのですが
(コメントアウトしてるのはもともと予定してた処理ですがとりあえず画像を映すだけに変えました)
ファイルはMain.cpp , Title.cpp , Title.hの3つです

コード:

  
//Main.cpp
#include "DxLib.h"
#include "Title.h"



int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        SetBackgroundColor( 255, 255, 255 );
			ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更,初期化,裏画面設定
			int I= LoadGraph( "Graph/I.png" ) ;
			int y=172, x1=66,x2=198;
		void Title_Initialize();
		
		while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
			
			void Title_Update();
		
			void Title_draw();
			
			//Iの文字の解像度は174*264
	
	
		}
	

		DxLib_End();
		return 0;
}

//Title.cpp
#include "DxLib.h"
//タイトルの画像を読み込む
int x1,x2,x3,x4,y1,y2,y3,y4;//画像の座標
int GHandleI,GHandleR,GHandleS;

void Title_Initialize()
{

	GHandleI = LoadGraph( "Graph/I.png" ) ;

	GHandleR = LoadGraph("Graph/R.png");

	GHandleS = LoadGraph("Graph/S.png") ;

x1=173,x2=173,y1=0,y2=173,x3=263,y3=0,x4=173,y4=263;

}

void Title_Update(){
	if(x1>=0){
	x1--;
	x2--;
	}
}

void Title_draw(){
	
	//Iの文字の解像度は174*264
	//DrawModiGraph(
		//x1,y1,
		//x2,y2,
		//x3,y3,
		//x4,y4,
		//GHandleI,TRUE)
		//;
	DrawGraph( 50 , 0 , GHandleI , FALSE ) ;
}

void Title_Delete(){
	DeleteGraph(GHandleI);
	DeleteGraph(GHandleR);
	DeleteGraph(GHandleS);
}

//Title.h
#ifndef DEF_TITLE //二重include防止

#define DEF_TITLE

//タイトルの画像を読み込む
void Title_Initialize();
//タイトル画像の計算
void Title_Update () ;

//タイトルの画像を描画する
void Title_draw();
//画像をメモリから消す関数
void Title_Delete();

#endif 

コード長くてすみません・・・
多分自分の知らない未知の関数などがあるのでしょうが・・・
ミスなどがあればすみません><

Re: ファイル分割について

Posted: 2013年5月01日(水) 00:12
by softya(ソフト屋)
WinMainのvoid Title_Initialize();ですが関数呼び出しではなく、関数のプロトタイプ宣言になっています。つまり呼び出されません。
型名 関数名();と書くと呼び出しではないのです。

それとインデントが狂っているので気をつけてくださいね。

Re: ファイル分割について

Posted: 2013年5月01日(水) 00:19
by てのん
呼び出す側の関数はVOIDがいらないということですか…
そこを変えたらちゃんと画像が表示されました

インデントも以後気をつけます

ありがとうごさいました!

Re: ファイル分割について

Posted: 2013年5月01日(水) 00:24
by softya(ソフト屋)
てのん さんが書きました:呼び出す側の関数はVOIDがいらないということですか…
そこを変えたらちゃんと画像が表示されました

インデントも以後気をつけます

ありがとうごさいました!
Title.hで、そう書いてますよね?
//タイトルの画像を読み込む
void Title_Initialize();
それと同じものだとしてコンパイラは処理します。これはCの文法です。
ヘッダに書くからプロトタイプ宣言となるのではなく、型名 関数名();と書けば何処に書いてもプロトタイプ宣言なのです。

Re: ファイル分割について

Posted: 2013年5月01日(水) 00:36
by てのん
解釈的にはMain.cppの中のメイン関数じゃないところで
プロトタイプ宣言(void Title_initialize();)をして、その処理内容を書いても
ヘッダ部分にプロトタイプ宣言をして処理内容を書いても
変わらないということでしょうか?

無知ですみません><

Re: ファイル分割について

Posted: 2013年5月01日(水) 00:51
by softya(ソフト屋)
プロトタイプ宣言は、こういう関数がありますって宣言しているだけです。何処かにあるのでリンクしてくださいって事だけを示します。
関数のプロトタイプ宣言は、関数の呼び出しから見える範囲(スコープ)にあれば文法的に許される場所であれば何処にあっても構いません。
この見える範囲(スコープ)の考え方は変数と同じです。
ヘッダに書くとグローバル変数、関数内ならローカル変数ですよね。見える範囲も同じです。

変数と違ってグローバルにするのに余り害がなく必要となる度に書くのが面倒なのでヘッダに書いているわけです。
まぁ、グローバル宣言は名前の衝突問題があるので、C++では名前空間で見える範囲を限定する機能が付きますけどね。

Re: ファイル分割について

Posted: 2013年5月01日(水) 01:10
by てのん
ふむふむ…
やはりコピペだけでは理解出来ていないですなぁ…

もう一つ疑問なのですが
二重インクルードってどういうエラー?というか
どういうことをしてはいけないのですか?

Re: ファイル分割について

Posted: 2013年5月01日(水) 10:48
by softya(ソフト屋)
てのん さんが書きました: もう一つ疑問なのですが
二重インクルードってどういうエラー?というか
どういうことをしてはいけないのですか?
複数ヘッダがあって、ヘッダ中でヘッダをインクルードしている場合に起こります。
AヘッダがAAヘッダをインクルードしていて、BヘッダもAAヘッダをインクルードしていた場合に迂闊にAヘッダとBヘッダをインクルードするとAAヘッダが2回にインクルードされる事になります。これが二重(多重)インクルードで、この場合はマクロなどが多重定義エラーに成る場合があります。

実はヘッダ・インクルードはすごく単純な機能で#lncludeとあったら呼び出しているヘッダ・ファイルの内容を展開するだけなのです。ファイル内容をコピペするって行ったほうが分かりやすいでしょうか。

ついでにもう一つヘッダ絡みの宣言と定義の違いを書いておきます。

宣言と定義の違いは分かりますか?
宣言は実体を伴わないモノを指します。今回のプロトタイプ宣言とかですね。
定義は実体を伴うモノを指します。関数の本文とか初期値の有る変数の事です。
この内、ヘッダに書いて良いのは宣言の方で実体を伴う定義は書いてはいけません。

なにが問題かというと、それはコンパイル・リンクのリンクで問題が出るからです。
引用画像:画像
この画像の、オブジェクトファイルはソースファイル毎に作られるのですが、定義を伴うヘッダが有った場合に同じ実体をもったオブジェクトファイルが出来てしまいます。
これを結合(リンク)しようとすると同じ実体が2つ以上出てくる事になるのでどれが本物!って事になりエラーを出して止まります。
ぜひ、実験して確かめて見てください。

Re: ファイル分割について

Posted: 2013年5月01日(水) 23:28
by てのん
ヘッダファイル内でインクルードできるということをここで初めて知ったくらいなのですが・・・
返信内容の例でしたらAヘッダでAAヘッダをインクルードして、BヘッダもAAヘッダをインクルードしただけならばエラーは出ないのでしょうか?
エラーが出るならばAAヘッダを別のものにして別の名前で付けるとか(調べたところコンパイルに時間がかかるとか・・・)
A.cppファイルでAAヘッダをインクルードしてB.cppファイルでAAヘッダをインクルードしてAヘッダとBヘッダをC.cppファイルでインクルードした時にはエラーが出ない?

なんだか謎が深まるばかりで・・・

Re: ファイル分割について

Posted: 2013年5月01日(水) 23:40
by softya(ソフト屋)
多重インクルードだけ例を書きます。
//main.cpp
#include "A.h"
#include "B.h"

//A.h
#include "AA.h"

//B.h
#include "AA.h"

//AA.h
enum { gomi };

とmain.cppと3つのヘッダでコンパイルしてみてください。
とこれだとエラーが出ないか。ちょっと修正します。
修正しました。