콜백함수
함수 포인터 + 함수 객체 + 템플릿
콜백 (Callback) : 다시 호출하다? 역으로 호출하다?
게임을 만들 때, 이런 콜백의 개념이 자주 등장한다.
ex) MoveTask 실습 등
어떤 상황이 일어나면 → 이 기능을 호출해줘
ex) UI 스킬 버튼을 누르면 → 스킬을 쓰는 함수를 호출 (함수 포인터 or 함수 객체 등 으로 넘겨줌)
함수 포인터는 사용 안했고, 함수 객체와 템플릿을 사용한 예
class Item
{
public:
int _itemId = 0;
int _rarity = 0;
int _ownerId = 0;
}
class FindByOwnerId
{
public:
// 함수 객체를 사용하기 위한 연산자 오버로딩
bool operator()(const Item* item)
{
return (item->_ownerId == _ownerId);
}
public:
int _ownerId;
}
class FindByRarity
{
public:
// 함수 객체를 사용하기 위한 연산자 오버로딩
bool operator()(const Item* item)
{
return (item->_rarity == _rarity );
}
public:
int _rarity;
}
// 함수 포인터, 함수 객체 대신 템플릿으로 유연하게 사용
template<typename T>
Item* FindItem(Item items[], int ItemCount, T selector)
{
for(int i = 0; i < ItemCount; ++i)
{
Item* item = &items[i]
// TODO : 조건체크
if (selector(item)) // 함수 객체
return item;
}
return nullptr;
}
int main()
{
Item items[10];
items[3]._ownerId = 100;
items[8]._rarity= 1;
FindByOwnerId functor1;
functor1._ownerId = 100;
FindByRarity functor2;
functor2._rarity= 1;
Item* item1 = FindItem(items, 10, functor1);
Item* item2 = FindItem(items, 10, functor2);
}
Item* FindItem(Item items[], int ItemCount, bool(*func)(const Item*))
함수 포인터인 경우는 상태(멤버)를 가질 수 없기 때문에 데이터를 제어할 수가 없고, 시그니처가 통일돼야 한다.
Item* FindItem(Item items[], int ItemCount, FindByOwnerId selector)
Item* FindItem(Item items[], int ItemCount, FindByRarity selector)
함수 객체는 인자가 명시적으로 들어갔기 때문에, 다른 클래스를 사용하고 싶으면 수정해야 한다.
물론 공통적인 부모클래스로 상속을 받아 캐스팅을 통해 가능할 수 있긴 한데, 그러면 조금 복잡하다.
메인 코드처럼 템플릿 형식으로 만들면 어떤 타입이든 범용적으로 작용할 수 있다.
결국에 콜백을 구현할 때, 함수 포인터든 함수 객체든 템플릿이든 기초 문법과 장단점을 알고 있으면 다양하게 선택해서 응용할 수 있다.
나중에 람다식을 이용하면 함수를 만들지 않고, 더 편하게 만들 수 있다.
'Script > C++' 카테고리의 다른 글
[C++] Chapter 09. 템플릿(Template) #2 (0) | 2023.05.12 |
---|---|
[C++] Chapter 08. 템플릿(Template) #1 (0) | 2023.05.12 |
[C++] Chapter 07. 함수 객체 (0) | 2023.05.12 |
[C++] Chapter 06. 함수 포인터 (0) | 2023.05.12 |
[C++] Chapter 05. 크러쉬가 나는 오작동 현상 (0) | 2023.05.12 |
댓글