함수 포인터는 함수를 가리키는 포인터입니다. 일반적인 포인터가 변수의 주소를 저장하는 것처럼, 함수 포인터는 함수의 주소를 저장하고 이를 호출하는 데 사용할 수 있습니다.
C++에서 함수 이름은 해당 함수의 주소를 의미하므로, 함수 포인터를 사용하면 특정 함수의 주소를 저장하고 필요할 때 호출할 수 있습니다.
#include <iostream>
using namespace std;
int Add(int a, int b)
{
return a + b;
}
int Sub(int a, int b)
{
return a - b;
}
int main()
{
// 1) 함수 포인터 선언
int (*fn)(int, int);
// 2) 함수 포인터에 특정 함수 할당
fn = &Add; // & 연산자는 생략 가능함 (fn = Add 도 가능)
// 3) 함수 포인터를 사용하여 함수 호출
int result = fn(1, 2); // Add(1, 2)와 동일
cout << "Result: " << result << endl;
// 4) 함수 포인터 사용 시 *(접근 연산자)를 사용할 수도 있음
int result2 = (*fn)(3, 5);
cout << "Result2: " << result2 << endl;
return 0;
}
✅ 해설
int (*fn)(int, int); → 두 개의 int를 인자로 받아 int를 반환하는 함수 포인터 fn을 선언합니다.fn = &Add; → 함수 포인터에 Add 함수를 할당합니다. &Add에서 &은 생략 가능함.fn(1, 2); → fn을 사용하여 Add 함수를 호출합니다.(*fn)(3, 5); → 함수 포인터를 호출할 때 *을 사용해도 동일하게 동작합니다.typedef 또는 using을 이용한 함수 포인터함수 포인터를 사용할 때 typedef 또는 using을 활용하여 더 가독성 좋게 작성할 수 있습니다.
#include <iostream>
using namespace std;
// typedef를 사용하여 함수 포인터 타입을 정의
typedef int(FUNC_TYPE)(int, int);
int Add(int a, int b) { return a + b; }
int main()
{
// 함수 포인터 선언 및 사용
FUNC_TYPE* fn = &Add;
cout << "Result: " << fn(2, 3) << endl;
return 0;
}
또는 using을 사용할 수도 있습니다.
using FUNC_TYPE = int(int, int);
int main()
{
FUNC_TYPE* fn = &Add;
cout << "Result: " << fn(5, 7) << endl;
return 0;
}
✅ 해설
typedef 또는 using을 활용하면 함수 포인터를 보다 간결하게 정의할 수 있습니다.함수 포인터를 사용하면 특정 조건을 만족하는 함수를 매개변수로 전달할 수 있습니다.
#include <iostream>
using namespace std;
// Item 클래스 정의
class Item {
public:
int _itemId;
int _rarity;
int _ownerId;
};
// 특정 조건을 만족하는 아이템을 찾는 함수
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)) // selector 함수 포인터를 통해 조건 검사
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; // 3번 아이템을 희귀 아이템으로 설정
// 희귀 아이템 찾기
Item* rareItem = FindItem(items, 10, IsRareItem, 2);
if (rareItem)
cout << "Rare item found!" << endl;
return 0;
}
✅ 해설
FindItem 함수는 ITEM_SELECTOR 타입의 함수 포인터를 매개변수로 받아서 특정 조건에 맞는 Item을 찾습니다.IsRareItem, IsOwnerItem 등의 함수는 FindItem에서 선택적으로 사용될 수 있습니다.멤버 함수 포인터는 클래스의 멤버 함수 주소를 저장할 수 있는 포인터입니다.
멤버 함수 포인터는 객체를 기반으로 호출해야 하기 때문에, 일반 함수 포인터와는 다른 방식으로 선언하고 사용해야 합니다.
#include <iostream>
using namespace std;
// Knight 클래스 정의
class Knight
{
public:
int GetHp(int, int)
{
cout << "GetHp() called" << endl;
return _hp;
}
public:
int _hp = 100;
};
int main()
{
Knight k1;
// 멤버 함수 포인터 선언
typedef int (Knight::*PMEMFUNC)(int, int);
// 멤버 함수 포인터에 GetHp 할당
PMEMFUNC mfn = &Knight::GetHp;
// 멤버 함수 호출 (객체를 기반으로 해야 함)
(k1.*mfn)(1, 1); // 멤버 함수 호출 방식
// 동적 할당된 객체를 통한 호출
Knight* k2 = new Knight();
(k2->*mfn)(1, 1);
delete k2;
return 0;
}
✅ 해설
PMEMFUNC를 Knight 클래스의 멤버 함수 포인터로 선언.&Knight::GetHp를 멤버 함수 포인터에 할당.k1.*mfn → k1 객체를 통해 멤버 함수 호출.k2->*mfn → 포인터 k2를 통해 멤버 함수 호출.