int a;
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;
// 함수의 이름은 함수의 시작 주소 (배열과 유사)
int result = Add(1, 2);
// push 2
// push 1
// call Add(0x.....)
// jmp 0x.....
cout << result << endl;
fn = Add;
result = fn(1, 2); // 기본 문법
result = (*fn)(1, 2); // 함수 포인터는 *(접근 연산자) 붙어도 함수 주소!
Item items[10] = {};
items[3]._rarity = 2; // RARE
Item* rareItem = FindItem(items, 10, IsRareItem);
bool IsRareItem(Item* item)
{
return item->_rarity >= 2;
}
// 단점은 다음과 같이 인자가 달라지는 경우
bool IsOwnerItem(Item* item, int ownerId)
{
return item->_ownerId == ownerId;
}
typedef bool(ITEM_SELECTOR)(Item* item);
Item* FindItem(Item items[], int itemCount, ITEM_SELECTOR* selector)
//Item* FindItem(Item items[], int itemCount, bool(*selector)(Item* item))
{
for (int i = 0; i < itemCount; i++)
{
Item* item = &items[i];
if (selector(item))
{
return item;
}
}
return nullptr;
}
int Test(int a, int b)
{
cout << "Test" << endl;
return a + b;
}
// 함수 포인터
// 1) 포인터 *
// 2) 변수의 이름 fn
// 3) 타입 함수(인자로 int 2개를 받고, int 1개를 반환)
int (*fn)(int, int);
//typedef int(FUNC_TYPE)(int, int);
//FUNC_TYPE* fn;
fn = Test; // & 생략 가능 (C언어와의 호환성 때문)
fn = &Test;
fn(1, 2);
(*fn)(1, 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);
//FUNC* fn;
PFUNC fn;
// 위 문법으로 [전역 함수 / 정적 함수]만 담을 수 있다 (호출 규약이 동일한 애들)
class Knight
{
public:
static void HelloKnight()
{
}
// 멤버 함수
int GetHp()
{
cout << "GetHp()" << endl;
return _hp;
}
public:
int _hp = 100;
};
Test(1, 2);
Knight k1;
k1.GetHp(1, 1);
// lea ecx, [k1] 자신을 ecx 레지스터에 넣은 다음,
// call Knight::GetHp (0F6143Dh) 호출
typedef int(Knight::*PMEMFUNC)(int, int); // 멤버 함수 포인터
PMEMFUNC mfn;
mfn = &Knight::GetHp;
// C언어 호환성 때문에 & 생략 가능했는데, 멤버 함수는 & 붙여야 됨.
(k1.*mfn)(1, 1); // k1 의 멤버와 구분을 위해 *을 꼭 붙인다?
Knight* k2 = new Knight();
((*k2).*mfn)(1, 1);
(k2->*mfn)(1, 1);
delete k2;