0. 포인터

주소값을 가지고 있는 저장 변수

int* ptr = &a;

(ex. int 형인 a 변수의 주소값을 가지고 있는 변수 ptr)

 

1. 함수 타입 재정의

    typedef int(FUNC_TYPE)(int a, int b); 
    using FUNC_TYPE = int(int a, int b);

FUNC_TYPE 이라는 타입은 int 형의 변수 두개를 받는다. 아래는 Modern C++ 문법이다.

 

 

2. 함수 포인터

    FUNC_TYPE* fn;

FUNC_TYPE 형인 데이터의 주소값을 저장하는 포인터가 fn이라는 뜻이다.

앞으로는 이 fn에 동일한 매개변수 형태를 가지는 데이터(함수)를 저장할 수 있다.

int Add(int a, int b)
{
    return a + b;
}

int main()
{
    typedef int(FUNC_TYPE)(int a, int b); 

    FUNC_TYPE* fn;
    
    fn = Add;
    
    int result = (*fn)(1, 2); // 함수 포인터는 *(접근 연산자)가 붙어도 함수 주소를 뜻함.
    int result = fn(1, 2); // 위와 동일하게 처리됨.
}

이번에는 동일한 매개변수 형태를 가지는 빼기 함수를 만들어본다.

int Sub(int a, int b)
{
    return a - b;
}

int main()
{
    typedef int(FUNC_TYPE)(int a, int b); 

    FUNC_TYPE* fn;

    fn = Sub;

    int result = (*fn)(1, 2); // 함수 포인터는 *(접근 연산자)가 붙어도 함수 주소를 뜻함.
    int result = fn(1, 2); // 위와 동일하게 처리됨.
}

출력은 -1이 정상적으로 출력되는 것을 알 수 있다.

 

3. 함수 포인터의 활용

ex) 인벤토리에서 아이템 찾기

class Item
{
public:
        Item() : _itemId(0), _rarity(0), _ownerId(0)
        {

        }

public:
    int _itemId; // 아이템
    int _rarity; // 희귀도
    int _ownerId; // 보유자 ID
};

Item* FindItem(Item items[], int itemCount)
{
    for (int i = 0; i < itemCount; i++)
    {
        Item* item = &items[i];
        return item;
    }

    return nullptr;
}

세가지 멤버 변수를 가지는 Item 클래스를 만들고 FindItem 함수를 만들어서 어떤 아이템을 찾도록 한다.

 

(1) 원하는 매개 변수를 받는 함수를 만든다.

bool IsRareItem(Item* item)
{
    return item->_rarity >= 2;
}

희귀도를 판별하는 불리언 함수를 만든다.

 

(2) 이 함수를 FindItem 내에서 함수 포인터를 매개 변수로 넘긴다.

Item* FindItem(Item items[], int itemCount, bool (*selector)(Item* item))
{//~~

또는

typedef bool(ITEM_SELECTOR)(Item* item);

Item* FindItem(Item items[], int itemCount, ITEM_SELECTOR* selector)
{ //~~

 

(3) rareItem을 찾는 코드를 main 함수 내에 작성한다.

    Item items[10] = {};
    items[3]._rarity = 2;
    Item* rareItem = FindItem(items, 10, IsRareItem);

 

4. 정리

동일한 개수와 형태의 매개 변수를 가지는 여러 함수들을 이 함수 포인터를 통해 조작이 가능하다.

'기초 C++ 스터디 > 객체지향' 카테고리의 다른 글

8-3. 함수 객체(Functor)  (0) 2023.06.08
8-2. 함수 포인터(2)  (0) 2023.06.08
6-7. 전방 선언 vs 포함(#include)  (0) 2023.06.05
6-5. 캐스팅  (0) 2023.06.02
6-4. 얕은 복사, 깊은 복사  (0) 2023.06.01