#include <iostream>
using namespace std;
//함수 포인터
// typedef의 진실...
// typedef 왼쪽 오른값 -> 오른쪽 (커스텀 타입 정의)
// 정확히는 왼쪽/오른쪽 기준이 아니라
// [선언 문법]에서 typedef을 앞에다 붙이는 쪽
typedef int NUMBER;
typedef int* POINTER;
typedef int FUNC(int, int);
typedef int ARRAY[20];
typedef int(*PFUNC)(int, int);
int Test(int a, int b) {
cout << "Test" << endl;
return 0;
}
class Knight {
public:
static int HelloKnight(int a, int b) {
return 0;
}
int GetHP() {
cout << "GetHp()" << endl;
return _hp;
}
public:
int _hp;
};
typedef int(Knight::* PMEMFUNC)(); //knight클래스의 멤버함수 포인터
int main()
{
// 함수 포인터
// 1) 포인터 *
// 2) 변수 이름 fn
// 3) 데이터 타입 int(int a, int b)
FUNC t; //단순 시그니처 식으론 사용할 수 없다.
FUNC* fn; //
PFUNC pfn;
pfn = Test;
//한번에 정의하는 방법
//int (*fn)(int, int); //함수 포인터 fn은 (int ,int)매개변수를 받아 int를 반환하는 함수를 담을 수 있는 포인터이다.
//나눠서 정의하는 방법
typedef int(FUNC_TYPE)(int, int);
FUNC_TYPE* fn2;
fn = Test;
fn = &Test;
fn(1, 2);
(*fn)(1, 2);
pfn(1, 2);
//위 문법으로는 [전역 함수 / 정적 함수]만 담을 수 있다
//fn=GetHP; 객체를 기반으로 하는 함수는 선언 불가. 멤버 함수이기 때문
fn = Knight::HelloKnight; //이건 static이기 때문에 가능
Knight k;
//k.GetHP();
PMEMFUNC pmfn =&Knight::GetHP; //멤버함수의 경우 편의상 &가 생략되지 않음
(k.*pmfn)(); //따라서 일반 함수 포인터르 작성할 때도 &를 사용하는게 좋다
Knight* k2;
(k2->*pmfn)(); //((*k2).*pmfn)();
return 0;
}