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);
}
-----------------------------------------------------------------------------