void(*Menu[/url])(void)={ Title, Protocol, Scene.Number, Loop.End, }; Menu();
C++で上のような感じの関数ポインタを作りたいのですが
関数のポインタとメンバ関数のポインタが混在していたり
メンバ関数のポインタだけでもエラーが出ます
書き方が間違っているのでしょうか?
環境は「Microsoft Visual C++ 2008 Express Edition」です
void(*Menu[/url])(void)={ Title, Protocol, Scene.Number, Loop.End, }; Menu();
class TestClass { public: void func(){} }; int main() { void (TestClass::*pfunc)() = &TestClass::func; //以下のようにして呼び出す TestClass tc; (tc.*pfunc)(); }メンバ関数が静的メンバならば、
void(*Menu[/url])(void)={ Title,//Title関数 Protocol,//Protocol関数 Scene.Number,//SceneクラスのNumber関数 Loop.End,//LoopクラスのEnd関数 };見たいな感じです
static void End(void){ flag=0; }
#include <stdio.h> // 関数バインドクラス群 class FuncBind { typedef void (FuncBind::*CallFuncType)( void ); protected: template<class T> FuncBind( void (T::*func)( void ) ):CallFuncPtr(reinterpret_cast<CallFuncType>(func)){ } public: void operator()( void ){ (this->*CallFuncPtr)(); } protected: void* FuncPtr; void* ClassPtr; private: CallFuncType CallFuncPtr; }; class GlobalFuncBind : public FuncBind { public: GlobalFuncBind( void (*f)( void ) ):FuncBind(&GlobalFuncBind::CallFunc){ FuncPtr = f; } void CallFunc( void ){ ((void (*)( void ))FuncPtr)(); } }; template<class T> class ClassFuncBind : public FuncBind { typedef void (T::*FuncType)( void ); public: ClassFuncBind( T* cls, FuncType f ):FuncBind(&ClassFuncBind::CallFunc){ void* p; __asm { // C++ 上では FuncType から void* に代入できないのでアセンブラで強引に mov eax, f mov p, eax } FuncPtr = p; ClassPtr = cls; } void CallFunc( void ){ FuncType func; void* p = FuncPtr; __asm { // C++ 上では void* から FuncType に代入できないのでアセンブラで強引に mov eax, p mov func, eax } (((T*)ClassPtr)->*func)(); } }; // 呼び出しクラス class Scene { public: void Number( void ){ printf("Scene::Number\n"); } }; class Loop { public: void End( void ){ printf("Loop::End\n"); } }; // 呼び出しグローバル関数 void Title( void ){ printf("Title\n"); } void Protocol( void ){ printf("Protocol\n"); } // 静的変数群 static Scene sScene; static Loop sLoop; static FuncBind MenuFuncs[/url] = { GlobalFuncBind(Title), GlobalFuncBind(Protocol), ClassFuncBind<Scene>(&sScene, &Scene::Number), ClassFuncBind<Loop>(&sLoop, &Loop::End), }; // メイン関数 int main( int argc, char* argv[/url] ){ for(int i = 0, n = sizeof(MenuFuncs) / sizeof(MenuFuncs[0]);i < n;++i){ MenuFuncs(); } getchar(); return 0; }
#include <iostream>
class State
{
public:
virtual void Update() = 0;
};
class Title :public State
{
public:
void Update()
{
std::cout << "タイトル\n";
}
};
class Menu :public State
{
public:
void Update()
{
std::cout << "メニュー\n";
}
};
class End :public State
{
public:
void Update()
{
std::cout << "エンド\n";
}
};
int main()
{
State* state[3];
state[0] = new Title();
state[1] = new Menu();
state[2] = new End();
int s = 0;
state->Update();
++s;
state->Update();
++s;
state->Update();
for(int i = 0; i < 3; ++i)
{
delete state;
}
};
こんな感じで、クラス内状態遷移ができれば良いのでしょうか? (下記のは、単純にメンバ関数を呼び出してるだけですが) -------------------------------------------------------------------------- #include<stdio.h> class Test{ public: Test(); ~Test(); void Top(void); private: typedef void(Test::*Func)(); Func fc[7]; void FuncA(void); void FuncB(void); void FuncC(void); void FuncD(void); void FuncE(void); void FuncF(void); void FuncG(void); }; Test::Test() { fc[0] = &Test::FuncA; fc[1] = &Test::FuncB; fc[2] = &Test::FuncC; fc[3] = &Test::FuncD; fc[4] = &Test::FuncE; fc[5] = &Test::FuncF; fc[6] = &Test::FuncG; } Test::~Test() { } void Test::Top(void) { for(int i = 0; i < 7; i++) (this->*fc)(); } void Test::FuncA(void) { printf("お茶\n"); } void Test::FuncB(void) { printf("ほうじ茶\n"); } void Test::FuncC(void) { printf("はと麦茶\n"); } void Test::FuncD(void) { printf("プーアール茶\n"); } void Test::FuncE(void) { printf("シルベスタギムネマ茶\n"); } void Test::FuncF(void) { printf("梅こぶ茶\n"); } void Test::FuncG(void) { printf("玉露\n"); } int main(void) { Test test; test.Top(); return(0); } --------------------------------------------------------------------------
switch(i){ case 1: A.Run(); break; case 2: B.Run(); break; case 3: C.Run(); break; }A,B,Cは全て別のクラスのインスタンスです
予め、どこのクラスのメンバ関数(全て同名)を実行するかを配列で定義しておくのならば、 こんな感じでどうでしょうか。 無理やり一つの.cppに纏めてしまったので、ちょっと見づらいと思います。 クラスごとに複数のヘッダファイルやソースファイルに分割すればよいかと。 ----------------------------------------------------------------------------- #include<stdio.h> #define SAFE_DELETE(p) { if (p) { delete (p); (p)=NULL; } } class Child{ public: virtual void Exec( void ) = 0; virtual ~Child(){ } }; class ChildC : public Child{ public: ChildC(){ }; ~ChildC(){ }; void Exec( void ); }; void ChildC::Exec(void) { printf("ChildC::Execです。\n"); } class ChildB : public Child{ public: ChildB(){ }; ~ChildB(){ }; void Exec( void ); }; void ChildB::Exec(void) { printf("ChildB::Execです。\n"); } class ChildA : public Child{ public: ChildA(){ }; ~ChildA(){ }; void Exec( void ); }; void ChildA::Exec(void) { printf("ChildA::Execです。\n"); } class Parent{ public: Parent(); ~Parent(); void Run(void); private: Child* mChild[3]; int ChildNum; }; Parent::Parent() { mChild[0] = new ChildA; mChild[1] = new ChildB; mChild[2] = new ChildC; ChildNum = sizeof(mChild)/sizeof(mChild[0]); } Parent::~Parent() { for(int i = 0; i < ChildNum; i++) SAFE_DELETE(mChild); } void Parent::Run(void) { for(int i = 0; i < ChildNum; i++) mChild->Exec(); } int main(void) { Parent p; p.Run(); return(0); } -----------------------------------------------------------------------------