콜백함수

CJB_ny·2022년 8월 23일
0

C++ 정리

목록 보기
65/95
post-thumbnail

콜백함수

다시 호출하다? 역으로 호출하다.

게임을 만들 때 이런 콜백 개념이 자주 등장함.

MoveTask실습등

어떤 상황이 일어나면 -> 이 기능을 호출해줘

UI스킬 버튼을 누르면 -> 스킬을 쓰는 함수를 호출해줘.

함수 포인터 + 함수 객체 + 템플릿

이런식으로 Item클래스가 있고

이상태에서 어떤 조건을 체크를 하기 위해서

(TODO에 들어갈조건 체크)

FindItem이라는 함수로 item을 찾는다고 가정을 하자.

함수포인터를 마지막 인자에 넘겨주어서

동작을 넣어 줄 수 있었다.

가장 간단한 방식으로 콜백을 넣어 줄 수 있다는 '강점'은 있지만

'어떤 상태를 저장할 수 없다.' 라는 단점이 존재한다.

그래서 등장한게 '함수 객체'이다.

함수 객체를 사용을 하면 '생성시점'과 '실행시점'을 구분할 수 있다는 장점이 생김.

간단한게 특정조건 하나를 체크를 하는 경우가 아니라면

이렇게 함수 포인터를 마지막 인자에 넣어서 동작을 넣어주면 불리하다.

_ownerId 라는 멤버변수도 함께 전달해주고 싶은 경우에.

그래서 일단 Functor를 만들어 줄 것이다.

이렇게 '상태'를 저장하기 위해서 _ownerId를 들고있도록 하자.

그리고 이 Functor도 '함수 처럼' 동작을 해야하니까

operator 를 '오버로딩' 해주도록 하자.

비교만 할꺼고 수정은 안할꺼라서 const Item* item을 받도록 하자.

이렇게 해주도록 하자.

마찬가지로 Rarity를 찾아주는 Functor도 같은 방식으로

'상태'를 가지고있고 operator ()를 통해 똑같이 구현을 해주면 될 것이다.

이렇게. (_rarity가 2 이상이면 레어 아이템으로 간주함)

이런식으로 늘릴 수가 있고

'함수 포인터'와는 다르게

객체가 독립적이다 보니까

이런식으로 데이터(상태)를 늘려줄 수 있을 것이다.

즉, 각기 다른 상태값을 가질 수 있다는 것이다.

그래서 이제 여기에 함수 포인터를 넘겨주는 것이 아니라

Functor라는 것 자체를 넘겨주면 될 것이다.

그런데 매개변수로 넘겨줄려면 '타입'이 있어야하기 때문에

이런식으로 까지는 아름답게 된다.

근데 이렇게 명시적으로 넣어 주었기 때문에

FinByRarity를 넘겨주고싶으면 다시 '명시적'으로 적어주어야한다.

(상속을 사용해서도 해결이 가능하지만 -> 복잡하다)

곰곰히 생각하면 마지막 인자로 받아주는 Functor는

결국 46번째 줄처럼 동작을 한다는 점이 공통적이다. (함수처럼 동작할 것이라는 점)

그래서 이전시간에 배운 템플릿을 사용해서

T라는 타입의 selector를 이제는 사용을 할 수 있을 것이다.

그러면이게 이제 FindByOwnerId일 수도있고 FindByRarity일 수도 있다.

그래서 이제 main에서

이렇게 functor를 만들어 주면

이제 FindItem 함수를 호출할 수 있다.

이렇게 넣어주고 이제 중요한데

이제 '콜백함수'를 넣어주는 개념이 될 것이다.

여기서 이제 functor1을 함수객체를 넣어주는 것이다.

(C++11의 람다 사용하면 functor를 만들지 않고 좀더 편하게 만들 수 있기는 하다)

그래서 이렇게 하면 강제로 넣어준 아이템 찾을 수 있다.

functor의 '생성'은 55, 59에서 하고

실행하는 부분은 FindItem을 호출하고 안에서 '실행 시점'이 잡히는 것이다.

functor1의 '상태'는 _ownerId가 10인 상태를 들고있고

여기서 이제 연산자 오버로딩을 해서 함수처럼 사용할 수 있도록 만들어 주었기 때문에

46번째줄이 '실행 시점'이다.

그래서 함수 포인터 + 함수 객체 + 템플릿을 잘 활용해야하고

STL을 공부하기 위한 기초가 됨.

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글