프로그래밍/c++

함수 포인터

오늘의논리 2023. 3. 4. 10:32
728x90
   int a = 10;

    typedef int DATA;



    DATA* pointer = &a;

 

이렇게 하면 int 타입을 DATA 사용할 있음

마찬가지로 함수도 방법이 있음

 

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


int main()
{

    int a = 10;
    typedef int DATA;

    DATA* pointer = &a;


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

    //1) 포인터       *
    //2) 변수이름     fn
    //3) 데이터 타입  함수(인자는int,int 반환은int)
    FUNC_TYPE* fn;//함수 포인터

    fn = Add;//함수의 이름은 함수의 시작 주소(배열과 유사)

    int result = fn(1, 2); // 기본문법
    cout << result << endl;
    int result2 = (*fn)(1, 2);// 함수 포인터는 *(접근연산자) 붙어도 함수 주소! 위에 기본문법이랑 같은 의미

    cout << result2 << endl;


    return 0;
}

 

int (*fn)(int)(int);

이렇게 선언이 기본임

 

근데 그냥 Add 함수를 호출하지 않느냐?

 

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

 

 

이런함수가 있다고 했을때 모든 fn Sub으로 바꾸고싶을때 유용

또한 아이템을 검색하는 함수를 만든다고 할때

 

 

class Item
{
public:

    Item() : _itemId(0), _rarity(0), _ownerId(0)
    {
    }

public:
    int _itemId; //아이템 구분 ID
    int _rarity; //희귀도
    int _ownerId; //소지자 ID


};


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))
            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; // RARE

    Item* rareItem = FindItem(items, 10, IsRareItem, 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);//이렇게 사용

 

class Knight
{

public:
    static void HelloKnight()//정적 함수 /  객체에 의존적인 정보를 수정불가(_hp같이)
    {
    }

    int GetHp(int, int) //멤버 함수
    {
        cout << "GetHp()" << endl;
        return _hp;
    }


public:
    int _hp = 100;

};


int main()
{

    //1) 포인터       *
    //2) 변수이름     fn
    //3) 데이터 타입  함수(인자는int,int 반환은int)
    PFUNC fn;

    //위 문법으로 [전역함수 / 정적함수]만 담을 수 있다(호출 규약이 동일한 애들)
    //fn = &Knight::GetHp; // 되지 않음
    return 0;

}


그렇게에 멤버함수 포인터는 다르게 선언해야함

typedef int(Knight::* PMEFUNC)(int, int);//멤버함수 포인터 버전 당연히 나이트 이후에 선언되야함





그 이후



int main()
{
    Knight k1;
    PMEFUNC mfn = &Knight::GetHp;
    (k1.*mfn)(1,1);

	Knight* k2 = new Knight(); // 포인터일경우
 	((*k2).*mfn)(1, 1);

	(k2->*mfn)(1, 1); //위에것과 같은 의미
    delete k2;

    return 0;
}

 

 

이렇게 사용할 수있음

 

포인터일경우

 

 

728x90
댓글수0