C++ Rookiss Part1 C++ 프로그래밍 입문 : 함수 포인터
🙇♀️함수 포인터
포인터는 포인터인데 따라가보니 함수가 있음
typedef bool(ITEM_SELETOR)(Item*, int);
처럼 만들거나 bool(*fn)(Item*, int)
처럼 사용함
🪐함수 포인터
typedef int DATA;
// 1) 포인터 *
// 2) 변수이름 pointer
// 3) 데이터 타입 int
DATA* pointer = &a;
// 함수
typedef int (FUNC_TYPE)(int a, int b);
//using FUNC_TYPE = int(int a, int b);
// 1) 포인터 *
// 2) 변수 이름 fn
// 3) 데이터 타입 함수 (인자는 int, int 반환은 int)
FUNC_TYPE* fn;
// 함수 포인터
fn = Sub; // 함수를 교체하면 아래 동작이 모두 바뀐다
// 함수의 이름은 함수의 시작 주소 (배열과 유사)
int result = fn(1, 2); // 기본 문법
cout << result << endl;
result = (*fn)(1, 2); // 함수 포인터는 *(접근 연산자) 붙여도 함수 주소!
cout << result << endl;
- 함수 포인터의 응용
class Item
{
public:
Item() : _itemId(0), _rearity(0), _ownerId(0)
{
}
public:
int _itemId; // 아이템을 구분하기 위한 ID
int _rearity; // 희귀도
int _ownerId; // 소지자 ID
};
typedef bool(ITEM_SELECTOR)(Item* itme, int value);
Item* FindItem(Item items[], int itemCount, ITEM_SELECTOR* selector, int value)
{
for (int i = 0; i < itemCount; i++)
{
Item* item = &items[i];
if (selector(item, value))
return item;
}
return nullptr;
}
bool IsRareItem(Item* item, int value)
{
return item->_rearity >= value;
}
bool IsOwnerItem(Item* item, int ownerId)
{
return item->_ownerId == ownerId;
}
int main()
{
Item items[10] = {};
items[3]._rearity = 2; // RARE
Item* rareItem = FindItem(items, 10, IsRareItem, 2);
Item* ownerItem = FindItem(items, 10, IsOwnerItem, 100);
return 0;
}
🪐함수 포인터 개념 정리
int Test(int a, int b) // 일반적인 함수
{
cout << "Test" << endl;
return a + b;
}
typedef int(FUNC_TYPE)(int, int);
FUNC_TYPE* fn;
로 단계별로 만들수 있지만 밑의 버전을 바로하는게 좋음
int (*fn)(int, int)
로 함수 포인터를 만든다
fn = Test;
함수 포인터에 함수를 넣는다. fn = &Test;
로 만들수 있다. &는 생략가능하지만 생략안하는걸 추천
fn(1, 2);
나 (*fn)(1, 2);
처럼 사용한다.
- typedef
typedef int(*PFUNC)(int, int);
함수 포인터 선언
PFUNC = fn;
fn = &Test;
대입
위 문법으로 [전역 함수 / 정적 함수]만 담을 수 있다. (호출 규약이 동일한 애들)
🪐멤버함수 포인터
typedef int(Knight::*PMEMFUNC)(int, int);
: 멤버 함수 포인터
PMEMFUNC mfn;
mfn = &Knight::GetHp;
로 멤버 함수를 담는다 &는 생략할 수 없다.
특정 객체가 있어야 함수를 호출 할 수 있다.
Knight k1;
으로 스택에 클래스를 들고있는 경우
(k1.*mfn)(1, 1);
로 사용
Knight* k2 = new Knight();
로 포인터로 들고있는 경우
((*k2).*mfn)(1, 1);
로 사용가능, (k2->*mfn)(1, 1);
로 사용가능