콜백(Call back)은 다시 호출하는, 역으로 호출하는 뜻을 가지고 있다
특히, 게임을 만들 때 이런 콜백의 개념이 자주 등장한다
간단한 실습을 통해 콜백 함수를 구현해 보자
먼저, 우리가 배운 함수 포인터로 콜백 함수를 구현하면
아래와 같이 작성이 될 것이다
class Item
{
public:
int _itemId = 0;
int _rarity = 0;
int _ownerId = 0;
};
Item* FindItem(Item items[], int itemCount, bool(*func)(const Item*))
{
for (int i = 0; i < itemCount; i++)
{
Item* item = &item[i];
// 조건 체크
return item;
}
}
하지만, 이렇게 함수 포인터를 통해 콜백 함수를 구현하면
가장 간단한 방식으로 구현해 내는 장점은 있지만
상태를 저장할 수 없는 단점과
여러 조건들을 유동적으로 사용하려면
결국 시그니쳐가 동일한 경우만 가능하기에
여러 단점과 한계가 있었다
그럼 이번에는 함수 객체를 통해 콜백 함수를 구현해 보자
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;
// 함수 포인터와 달리 각 객체가 독립적이기에
// 원하는, 필요한 데이터를 더 담을 수 있음
};
Item* FindItem(Item items[], int itemCount, FindByOwnerId selector)
{
for (int i = 0; i < itemCount; i++)
{
Item* item = &item[i];
if(selector(item))
return item;
}
}
그런데,
문제는 지금은 FindItem의 함수에 인자로 들어오는
FindByOwnerId selector를 받았지만
상황에 따라 계속 저 부분을
FindByRarity selector 이런 식으로 수정을 해줘야 하기 때문에 매우 불편하다
이 부분을 해결하기 위해서,
상속을 이용해 부모 클래스로 받는 방법을 고려해 볼 수도 있겠지만
우리가 배운 템플릿을 이용하면 이 부분을 쉽게 해결할 수 있다
아래를 통해 알아보자
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 = &item[i];
if(selector(item))
return item;
}
}
이제 함수 객체와 템플릿을 통해 만들어진 콜백 함수를
사용해 보는 예시를 아래의 코드를 통해 알아보자
main 함수부터 보면 된다
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];
if(selector(item))
return item;
}
return nullptr;
}
int main()
{
Item items[10];
items[3]._ownerId = 100;
items[8]._rarity = 2;
FindByOwnerId functor1; // 함수 객체 생성
functor1._ownerId = 100;
FindByRarity functor2;
functor2._rarity = 1;
Item* item1 = FindItem(items, 10, functor1); // 함수의 인자로 함수 객체를 받음
Item* item2 = FindItem(items, 10, functor2);
}
이렇게 해서 콜백 함수를 구현하는 다양한 방식을 알아보았다
STL을 공부하기 위한 사전 지식은 모두 끝났다
'C++ > [루키스] 콜백함수' 카테고리의 다른 글
[STL 사전지식] 5. 템플릿 기초 (2) (0) | 2023.01.25 |
---|---|
[STL 사전지식] 4. 템플릿 기초 (1) (0) | 2023.01.25 |
[STL 사전지식] 3. 함수 객체 (0) | 2023.01.23 |
[STL 사전지식] 2. 함수 포인터 (2) (0) | 2023.01.22 |
[STL 사전지식] 1. 함수 포인터 (1) (0) | 2023.01.22 |