프로그래밍/c++
함수 포인터
오늘의논리
2023. 3. 4. 10:32
728x90
int a = 10;
typedef int DATA;
DATA* pointer = &a;
이렇게 하면 int 타입을 DATA로 사용할 수 있음
마찬가지로 함수도 방법이 있음
int Add(int a, int b)
{
return a + b;
}
int main()
{
int a = 10;
typedef int DATA;
DATA* pointer = &a;
typedef int(FUNC_TYPE)(int a, int b);
//using FUNC_TYPE = int(int a, int b);
//typedef int(FUNC_TYPE2)(int);
//1) 포인터 *
//2) 변수이름 fn
//3) 데이터 타입 함수(인자는int,int 반환은int)
FUNC_TYPE* fn;//함수 포인터
fn = Add;//함수의 이름은 함수의 시작 주소(배열과 유사)
int result = fn(1, 2); // 기본문법
cout << result << endl;
int result2 = (*fn)(1, 2);// 함수 포인터는 *(접근연산자) 붙어도 함수 주소! 위에 기본문법이랑 같은 의미
cout << result2 << endl;
return 0;
}
int (*fn)(int)(int);
이렇게 선언이 기본임
근데 왜 그냥 Add 함수를 호출하지 않느냐?
int Sub(int a, int b)
{
return a - b;
}
이런함수가 있다고 했을때 모든 fn을 Sub으로 바꾸고싶을때 유용
또한 아이템을 검색하는 함수를 만든다고 할때
class Item
{
public:
Item() : _itemId(0), _rarity(0), _ownerId(0)
{
}
public:
int _itemId; //아이템 구분 ID
int _rarity; //희귀도
int _ownerId; //소지자 ID
};
typedef bool(ITEM_SELECTOR)(Item*, int);
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->_rarity >= value;
}
bool IsOwnerItem(Item* item, int ownerId)
{
return item->_ownerId == ownerId;
}
int main()
{
Item items[10] = {};
items[3]._rarity = 2; // RARE
Item* rareItem = FindItem(items, 10, IsRareItem, 2);
return 0;
}
이런식으로 레어리티 를 따로 넣는 등 코드를 줄일 수 있음
typedef의 진실
typedef 왼쪽값 ->오른쪽(커스텀 타입 정의)
정확히는 왼쪽/ 오른쪽 기준이 아니라
[선언문법]에서 typedef 을 앞에다 붙이는 쪽
typedef int INTEGER;
typedef int* POINTER;
typedef int FUNC(int, int);//이것보다는
typedef int ARRAY[20];
typedef int(*PFUNC)(int, int);//이렇게 사용
class Knight
{
public:
static void HelloKnight()//정적 함수 / 객체에 의존적인 정보를 수정불가(_hp같이)
{
}
int GetHp(int, int) //멤버 함수
{
cout << "GetHp()" << endl;
return _hp;
}
public:
int _hp = 100;
};
int main()
{
//1) 포인터 *
//2) 변수이름 fn
//3) 데이터 타입 함수(인자는int,int 반환은int)
PFUNC fn;
//위 문법으로 [전역함수 / 정적함수]만 담을 수 있다(호출 규약이 동일한 애들)
//fn = &Knight::GetHp; // 되지 않음
return 0;
}
그렇게에 멤버함수 포인터는 다르게 선언해야함
typedef int(Knight::* PMEFUNC)(int, int);//멤버함수 포인터 버전 당연히 나이트 이후에 선언되야함
그 이후
int main()
{
Knight k1;
PMEFUNC mfn = &Knight::GetHp;
(k1.*mfn)(1,1);
Knight* k2 = new Knight(); // 포인터일경우
((*k2).*mfn)(1, 1);
(k2->*mfn)(1, 1); //위에것과 같은 의미
delete k2;
return 0;
}
이렇게 사용할 수있음
포인터일경우
728x90