クラスをインクルードファイルで引っ張ってきたいのですが

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
サンタクロース
記事: 8
登録日時: 13年前

クラスをインクルードファイルで引っ張ってきたいのですが

#1

投稿記事 by サンタクロース » 13年前

こんばんは、サンタクロースです
今回も初歩的な質問ですが回答お願いします

まずはソースを張ります

コード:

---------------------play.h------------------------------------------------

#ifndef INCLUDE_PLAY
#define INCLUDE_PLAY

#include "mainloop.h"

class Play{

private:

	int a;

public:

	Play();//コンストラクタ

	~Play();//デストラクタ

	void update(MainLoop :: SeqID* parent);//更新関数
	void moveTo(MainLoop :: SeqID* parent);//外部からの状態遷移


};

---------------------play.cpp------------------------------------------------
#include "mainloop.h"
#include "DxLib.h"
//コンストラクタ
Play :: Play(){

	printfDx("Playクラスが生成されました");

}

//デストラクタ
Play :: ~Play(){

	printfDx("Playクラスが解放されました");

}

void Play :: update(MainLoop :: SeqID* parent){


}

void Play :: moveTo(MainLoop :: SeqID* parent){


}

--------------------------------------mainloop.h---------------------------------
#ifndef INCLUDE_MAINLOOP
#define INCLUDE_MAINLOOP

#include "charSelect.h"
#include "stageSelect.h"
#include "title.h"
#include "play.h"


class MainLoop{

public:

	//列挙型を宣言
	enum SeqID{

		SEQ_TITLE,
		SEQ_CHARACTER_SELECT,
		SEQ_STAGE_SELECT,
		SEQ_PLAY,
		SEQ_NONE

	};

	MainLoop();//コンストラクタ
		
	~MainLoop();//デストラクタ

	void update();//アップデート関数

	void setStageID(int stageID);

	int count;

private:

	int mStageID;//ステージ番号を表す
	SeqID mNow;//今実行している状態
	SeqID mNext;//次のフレームの状態を表す列挙型変数

	//mainloopが管理する子クラス
	Title* mTitle;
	CharacterSelect* mCharacterSelect;
	StageSelect* mStageSelect;
	Play* mPlay;
	

};

#endif
また以下のようなエラーが発生しました

play.h(20):error C2653: 'MainLoop' : 識別子がクラス名でも名前空間名でもありません。
play.h(20):error C2061: 構文エラー : 識別子 'SeqID'
play.cpp(16):error C2511: 'void Play::update(MainLoop::SeqID *)' : オーバーロードされたメンバー関数が 'Play' にありません。
play.cpp(21):error C2511: 'void Play::moveTo(MainLoop::SeqID *)' : オーバーロードされたメンバー関数が 'Play' にありません。

これはMainLoopクラスが正常にインクルードされていないということでしょうか?
私的には、Play.hの4行目で#include "mainloop.h"と宣言しているのでMainLoopクラスを使えるはずだと思うのですが、ちょっと原因がわかりません。
何か初歩的なことが理解できていない気もしますが、皆さんの助言をいただきたいと思います。

そもそも、#include ""というのは "ヘッダーファイル名" をヘッダーファイル内のソースコードに置き換えるというもので好かったでしょうか
最後に編集したユーザー サンタクロース on 2012年5月09日(水) 01:07 [ 編集 1 回目 ]

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: クラスをインクルードファイルで引っ張ってきたいのですが

#2

投稿記事 by h2so5 » 13年前

play.h に #endif が無くて
mainloop.h に #endifが二つあるのがおかしいですね。

サンタクロース
記事: 8
登録日時: 13年前

Re: クラスをインクルードファイルで引っ張ってきたいのですが

#3

投稿記事 by サンタクロース » 13年前

回答ありがとうございます
うっかりしていましたが、#endifが連続しているのは、貼り付けの際のミスです、紛らわしくてすみません;;

かずま

Re: クラスをインクルードファイルで引っ張ってきたいのですが

#4

投稿記事 by かずま » 13年前

mainloop.h の中の #include "play.h" を削除し、class play; を追加。
play.cpp の中の #include "mainloop.h" を #include "play.h" に変更。

とっち
記事: 56
登録日時: 13年前
住所: 岡山

Re: クラスをインクルードファイルで引っ張ってきたいのですが

#5

投稿記事 by とっち » 13年前

落ち着いて考えてみましょう。

ヘッダファイルの中身はコンパイル時に
#include ".h"のところに展開されます。

今、たとえばmainloop.hが先に呼ばれたとします。

1. mainloop.h内に#include "play.h"があるので展開
2. play.h内に#include "mainloop.h"があるのでそれも展開
3.インクルードガードがあるので一回しか展開されない(これは自信ないです「無限に展開されるかも」)

展開されたのを見ると、下のようになります。

コード:

class Play{
 
private:
 
    int a;
 
public:
 
    Play();//コンストラクタ
 
    ~Play();//デストラクタ
 
    void update(MainLoop :: SeqID* parent);//更新関数
    void moveTo(MainLoop :: SeqID* parent);//外部からの状態遷移
 
 
};

class MainLoop{
 
public:
 
    //列挙型を宣言
    enum SeqID{
 
        SEQ_TITLE,
        SEQ_CHARACTER_SELECT,
        SEQ_STAGE_SELECT,
        SEQ_PLAY,
        SEQ_NONE
 
    };
 
    MainLoop();//コンストラクタ
        
    ~MainLoop();//デストラクタ
 
    void update();//アップデート関数
 
    void setStageID(int stageID);
 
    int count;
 
private:
 
    int mStageID;//ステージ番号を表す
    SeqID mNow;//今実行している状態
    SeqID mNext;//次のフレームの状態を表す列挙型変数
 
    //mainloopが管理する子クラス
    Title* mTitle;
    CharacterSelect* mCharacterSelect;
    StageSelect* mStageSelect;
    Play* mPlay;
    
 
};

class Play{
 
private:
 
    int a;
 
public:
 
    Play();//コンストラクタ
 
    ~Play();//デストラクタ
 
    void update(MainLoop :: SeqID* parent);//更新関数
    void moveTo(MainLoop :: SeqID* parent);//外部からの状態遷移
 
 
};
cやc++は上から順にコンパイルしていくので、一回目の

コード:

class Play{
   void update(...);
   void moveTo(...);
}
のupdate関数はMainLoopってなに?ってなるわけです。
よってこのようなエラーが出ます。

サンタクロース
記事: 8
登録日時: 13年前

Re: クラスをインクルードファイルで引っ張ってきたいのですが

#6

投稿記事 by サンタクロース » 13年前

>>かずまさん、とっちさん回答ありがとうございました。

とっちさんのいうように、ソースファイルの内容を置き換え、展開してみたら理解しやすかったです。
それ以前に僕の書いたソースでは、"mainloop.h"が"play.h"、"play.h"が"mainloop.h"を呼んでいたので
無限ループのような形になっていたようです。実際無限ループが起きてもおかしくないのに起きなかったことが少し不思議ですが;;

片方をclass ~ として宣言することで、「~のクラスが使われますよ」と伝えておくのですね。
たしか、この宣言は前方宣言?だったと思います。

インクルードガードがあるからと言って、適当にインクルードしてしまうとエラーが起こることが良くわかりました。
以降はちゃんとインクルードファイルを展開後、どうなるのかを少し意識しながら組んでいきたいと思います

閉鎖

“C言語何でも質問掲示板” へ戻る