블로그는 나의 힘!

함수 포인터를 이용하여 함수를 만든 후
STL map에 담아 관리 하는 시스템을 만들어야 할 때가 있다.

typedef int ( *pComponent )( int nParam1, int nParam2 );

class CComponentSystem
{
     typedef std::map< int, pComponent > WORKING_HANDLE_MAP;
     typedef WORKING_HANDLE_MAP::const_iterator WORKING_HANDLE_MAP_CONST_IT;

public:
     CComponentSystem() { Initialize(); __initHandlerFunction(); }
     ~CComponentSystem() {}

     void Initialize() { m_mapWorkingList.clear(); }
     bool IsHandleFunction(int nIndex) const
     {
          WORKING_HANDLE_MAP_CONST_IT constIter = m_mapWorkingList.find(nIndex);
          return (m_mapWorkingList.end() == constIter)? false : true;
     }
     int HandleWorkingFunction( int nIndex, int nParam1, int nParam2 )
     {
          pHandleWorking func = GetHandleFunction( nIndex );
          if (nullptr == func) return 0;
          return ( this->*func )( nParam1, nParam2 );
     }

protected:
     int _Component_1( int nParam1, int nParam2 )
     {
          UNREFERENCED_PARAMETER(nParam1);
          UNREFERENCED_PARAMETER(nParam2); return 1;
     }
     int _Component_2( int nParam1, int nParam2 )
     {
          UNREFERENCED_PARAMETER(nParam1);
          UNREFERENCED_PARAMETER(nParam2);
          return 2;
     }
     int _Component_3( int nParam1, int nParam2 )
     {
          UNREFERENCED_PARAMETER(nParam1);
          UNREFERENCED_PARAMETER(nParam2);
          return 3;
     }

private:
     pHandleWorking GetHandleFunction(int nIndex) { return m_mapWorkingList[nIndex]; }
     void __registerHandleFunction( int nIndex, const pHandleWorking& handler )
     {
          m_mapWorkingList[nIndex] = handler;
     }
     void __initHandlerFunction()
     {
          __registerHandleFunction( 1, &CWorkingComponent::_Component_1 );
          __registerHandleFunction( 2, &CWorkingComponent::_Component_2 );
          __registerHandleFunction( 3, &CWorkingComponent::_Component_3 );
     }

private:
     WORKING_HANDLE_MAP m_mapWorkingList;
};


해당 시스템을
STL function 으로 만든다면,

class CComponentSystem
{
     using HandleFunction = std::function<int( int, int )>;
     using FUNCTION_HANDLE_MAP = map< int, HandleFunction >;

public:
    CComponentSystem() { __initHandlerFunction(); }
     ~CComponentSystem() {}

     void Initialize() { m_mapWorkingList.clear(); }
     bool HandleWorkingFunction( int nKey, int nParam1, int nParam2 )
     {
          HandleFunction& handleFuction = m_mapTBLMission[nKey];
          if (nullptr == handleFuction)
               return false;
          return handleFuction( nID, pSession, pInfo );
     }

protected:
     int _Component_1( int nParam1, int nParam2 )
     {
          UNREFERENCED_PARAMETER(nParam1);
          UNREFERENCED_PARAMETER(nParam2);
          return 1;
     }
     int _Component_2( int nParam1, int nParam2 )
     {
          UNREFERENCED_PARAMETER(nParam1);
          UNREFERENCED_PARAMETER(nParam2);
          return 2;      }
     int _Component_3( int nParam1, int nParam2 )
     {
          UNREFERENCED_PARAMETER(nParam1);
          UNREFERENCED_PARAMETER(nParam2);
          return 3;
     }

private:
     void __registerHandleFunction( int nIndex, const HandleFunction&& handler )
     {
          // 이동 생성.
          m_mapTBLMission.emplace( make_pair(nIndex, handler) );
     }
     void __initHandlerFunction()
     {
          __registerHandleFunction( 
               1, 
               std::bind( &CWorkingComponent::_Component_1, this, placeholders::_1, placeholders::_2 )
                );
          __registerHandleFunction(
                2,
               std::bind( &CWorkingComponent::_Component_2, this, placeholders::_1, placeholders::_2 )
                );
          __registerHandleFunction( 
               3, 
               std::bind( &CWorkingComponent::_Component_3, this, placeholders::_1, placeholders::_2 ) 
               ); 
     }

private:
     FUNCTION_HANDLE_MAP m_mapWorkingList;
};


[ STL function ]
( 링크 : cplusplus.com/doc/tutorial/functions , en.cppreference.com/w/cpp/utility/functional/function )
: 쉽게 말해 STL 함수 포인터. 범용 다형성 함수 레퍼런스.
기존 함수 포인터와의 차이점은 타입 선언이 아닌 객체.
함수, 람다, 바인드, 객체, 포인터 여러 대상을 저장, 복사, 및 호출 가능.

[ STL bind ]
( 링크 : en.cppreference.com/w/cpp/utility/functional/bind , cplusplus.com/reference/functional/bind )
: 함수 호출 레퍼런스를 생성. 인수 중 일부를 바인딩 하여 함수를 호출 하는 방식.

[ 그 외 function pointer vs functors in C++ ]
링크 https://stackoverflow.com/questions/37635300/function-pointer-vs-functors-in-c

[ STL Map insert & emplace ]
: insert는 기본적으로 복사 생성자가 호출 되고 삽입 시 2번 이상의 복사 생성이 발생함.
  emplace는 복상 생성 -> 이동 생성으로 연결. 즉, 이동 생성자를 지원함.
  복사가 필요한 시점에는 insert 필요. 필요에 따라 각자 다른 메소드 제공 함수를 쓰자.

 

'[ Programing ] > STL & Booster' 카테고리의 다른 글

C++ STL mutex  (0) 2022.01.21
C++ STL fill_n / fill  (0) 2021.01.22
C++ stl numeric_limits  (0) 2020.06.10
C++17. STL variant  (0) 2020.06.08
C++ STL shuffle.  (0) 2020.06.08
Posted by Mister_Q