たにです。昨日は大変お世話になりました。
( http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200803/08030024.txt)
もう一点だけご教授頂きたいのですが、
下記に提示したソースをコンパイルすると以下のエラーが出ます。
-------------------------------------
.\State.cpp(25) : error C2512: 'EngineIdle' : クラス、構造体、共用体に既定のコ
ンストラクタがありません。
.\State.cpp(52) : error C2512: 'EngineRunningLow' : クラス、構造体、共用体に既
定のコンストラクタがありません。
.\State.cpp(75) : error C2512: 'EngineRunningHigh' : クラス、構造体、共用体に既
定のコンストラクタがありません。
-------------------------------------
調べた所、前方宣言ではクラスの名前しか宣言出来ず、
そのサイズまでは特定出来ないからとの事で、
要はインスタンスを生成する前に定義が存在しない為に、
発生したエラーと考え、単純に該当する部分をクラスの
定義外に実装した所動作致しました。
(下記ソースでのコメント部分有効にした。)
これは、私の実装の仕方に問題があるのか、C++の仕様上
仕方のない事なのかを教えて頂きたいと思い質問した次第です。
もし作りの問題であれば、参考までにセオリーと言うか、
どう組むのがスマートであるかをご教授頂ければ嬉しいです。
何卒宜しくお願い致します。環境はWinXPPro/VC++2005です。
文字数制限にひっかかってしまったので、
ソースは次のコメントで・・・。
以下ソース
--------------------------------------------------
#include stdafx.h
#include <iostream>
using namespace std;
// 前方宣言
class EngineBox;
class EngineIdle;
class EngineState;
class EngineRunningHigh;
class EngineRunningLow;
class EngineState{
public:
EngineState(){};
virtual ~EngineState(){};
virtual void Up(EngineBox *eb){}
virtual void Down(EngineBox *eb){}
virtual void ShowCurrentState(){}
};
class EngineBox{
public:
EngineState *state;
//-----------------------------------------------
EngineBox(){ state = new EngineIdle(); } // 最初はIdle状態
~EngineBox(){ delete state;}
/*-----------------------------------------------
EngineBox();
~EngineBox();
-----------------------------------------------*/
void Up(){
state->Up(this);
}
void Down(){
state->Down(this);
}
void ChangeState(EngineState *newState){
delete state;
state = newState;
state->ShowCurrentState();
}
};
class EngineIdle :public EngineState{
public:
EngineIdle(){};
~EngineIdle(){};
//-----------------------------------------------
void Up(EngineBox *eb){
cout << Idle→Low << endl;
eb->ChangeState(new EngineRunningLow());
}
/*-----------------------------------------------
void Up(EngineBox *eb);
-----------------------------------------------*/
void Down(EngineBox *eb){
cout << No Change << endl;
eb->ChangeState(new EngineIdle());
}
void ShowCurrentState(){
cout << State:Idle << endl;
}
};
class EngineRunningLow : public EngineState{
public:
EngineRunningLow(){};
~EngineRunningLow(){};
//-----------------------------------------------
void Up(EngineBox *eb){
cout << Low→Hign << endl;
eb->ChangeState(new EngineRunningHigh());
}
/*-----------------------------------------------
void Up(EngineBox *eb);
------------------------------------------------*/
void Down(EngineBox *eb){
cout << Low→Idle << endl;
eb->ChangeState(new EngineIdle());
}
void ShowCurrentState(){
cout << State:Low << endl;
}
};
class EngineRunningHigh : public EngineState{
public:
EngineRunningHigh(){};
~EngineRunningHigh(){};
void Up(EngineBox *eb){
cout << No Change << endl;
eb->ChangeState(new EngineRunningHigh());
}
void Down(EngineBox *eb){
cout << High→Low << endl;
eb->ChangeState(new EngineRunningLow());
}
void ShowCurrentState(){
cout << State:High << endl;
}
};
/*--------------------------------------------------
EngineBox::EngineBox(){ state = new EngineIdle(); }
EngineBox::~EngineBox(){ delete state;}
void EngineIdle::Up(EngineBox *eb){
cout << Idle→Low << endl;
eb->ChangeState(new EngineRunningLow());
}
void EngineRunningLow::Up(EngineBox *eb){
cout << Low→Hign << endl;
eb->ChangeState(new EngineRunningHigh());
}
------------------------------------------------*/
int _tmain(int argc, _TCHAR* argv[])
{
EngineBox *ebox;
ebox = new EngineBox();
ebox->Up();
ebox->Down();
ebox->Up();
ebox->Down();
return 0;
}
---------------------------
ソースここまで。
宜しくお願い致します。
宣言と定義をわけて記述してみてはどうでしょうか?
まずは、1クラス、XXXX.h、XXX.cpp となるようにして
うまいことインクルードさせる。
> まずは、1クラス、XXXX.h、XXX.cpp となるようにして
> うまいことインクルードさせる。
参考までに。
http://www7b.biglobe.ne.jp/~robe/cpphtml/index.html
http://www7b.biglobe.ne.jp/~robe/cpphtml/html01/cpp01027.html
http://www7b.biglobe.ne.jp/~robe/cpphtml/html02/cpp02007.html
分割コンパイルだけでなく、ざっと全ページ目を通すのもお勧めです。
全ページ精読して全コードを走らせるのがよりお勧めです。