함수 포인터를 이용하여 함수를 만든 후
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 |