전체 코드

1. 함수 포인터(Function Pointer)

함수 포인터는 함수를 가리키는 포인터입니다. 일반적인 포인터가 변수의 주소를 저장하는 것처럼, 함수 포인터는 함수의 주소를 저장하고 이를 호출하는 데 사용할 수 있습니다.
C++에서 함수 이름은 해당 함수의 주소를 의미하므로, 함수 포인터를 사용하면 특정 함수의 주소를 저장하고 필요할 때 호출할 수 있습니다.


1.1 기본적인 함수 포인터 예제

#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); → 함수 포인터를 호출할 때 *을 사용해도 동일하게 동작합니다.

1.2 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을 활용하면 함수 포인터를 보다 간결하게 정의할 수 있습니다.

1.3 함수 포인터를 활용한 함수 전달

함수 포인터를 사용하면 특정 조건을 만족하는 함수를 매개변수로 전달할 수 있습니다.

#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에서 선택적으로 사용될 수 있습니다.

2. 멤버 함수 포인터(Member Function Pointer)

멤버 함수 포인터는 클래스의 멤버 함수 주소를 저장할 수 있는 포인터입니다.
멤버 함수 포인터는 객체를 기반으로 호출해야 하기 때문에, 일반 함수 포인터와는 다른 방식으로 선언하고 사용해야 합니다.


2.1 멤버 함수 포인터 선언 및 사용

#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;
}

해설

  • PMEMFUNCKnight 클래스의 멤버 함수 포인터로 선언.
  • &Knight::GetHp를 멤버 함수 포인터에 할당.
  • k1.*mfnk1 객체를 통해 멤버 함수 호출.
  • k2->*mfn → 포인터 k2를 통해 멤버 함수 호출.

profile
李家네_공부방

0개의 댓글