멤버 함수 포인터4

4장에서 내가 필요한 것을 구현하게 되었다.

C#의 Deleage나 Boost의 bind를 완벽하게 구현 하면 좋지만, 나에게 필요한건 어디까지나, 문자열을
받아서 특정 객체의 메쏘드를 실행만 해주면 되므로 더 이상의 복잡한 코드는 필요 하지 않다.

member_function_pointer1.html

member_function_pointer2.html

member_function_pointer3.html

CmdTable4.zip

이번 장은 위의 장들을 참고로 한 설명이다.

그러므로 간단하게 사용 방법만 설명하겠다.

명령어 추가

MakeCmd를 통하여 문자열과 멤버함수를 넘겨주면 Add()에서 cmdTable에 추가한다.
멤버 함수를 어떻게 채울 것인가? 이것은 뒤에 실제 사용법에서 설명한다.

typedef std::pair<const char*, IFunctionImp*>            MakeCmd;

typedef std::map<const char*, IFunctionImp*, StriLess >  CmdMap;

 

//CmdMap cmdTable

void Command::Add( const char* strCmd, IFunctionImp* imp)

{

    cmdTable.insert( MakeCmd( strCmd, imp ) );

}

명령어 실행

IFunctionImp의 Process()를 실행한다.  사용만 한다면 내부에 어떻게 실행되는지 모르더라도 크게 문제 없다.

void Command::Process( char* str )

{

    CmdMap::iterator iter = cmdTable.find( str );

    if( iter != cmdTable.end() )

    {

        (iter->second)->Process();

    }

}

실제 사용법

#define MakeFunc( a, b, c )   new FunctionImp<b>( &a, &b::c)

 

void main()

{

    Command command;

 

    Lion lion;

    command.Add( "Run", new FunctionImp<Lion>(&lion, &Lion::Run) );

    Tiger tiger;

    command.Add( "Idle", new FunctionImp<Tiger>(&tiger, &Tiger::Idle) );

 

    command.Add( "Attack", MakeFunc( lion, Lion, Attack ) );

 

    command.Process( "Run" );

    command.Process( "Idle" );

    command.Process( "Attack" );

}

 

command.Add( "Run", new FunctionImp<Lion>(&lion, &Lion::Run) )

 

"Run"은 명령을 호출 할 때 필요한 문자열이다.
FunctionImp의 템플리트는 Lion, 생성자 첫 번째 인자는 객체(lion), 두 번째 인자는 실행할 메쏘드이다.

MakeFunc 디파인문에 의해서  다음과 같이 추가 할 수도 있다.

 

command.Add( "Attack", MakeFunc( lion, Lion, Attack ) )

 

이것도 별로 보기엔 좋지가 않다. 그냥 디파인문 없이 사용하는게 좋겠다.

여기서 한가지 확장할 필요가 있다.

FunctionImp에 추가 할 수 있는 메쏘드가 void Run()의 메쏘드처럼 리턴값과 인자가 void형만
사용해야 하는 제약이 있다.

 

오늘은 피곤해서 여기 까지만.....