C++프로그래밍/자료구조,알고리즘(추후확장)

함수포인터

season97 2024. 9. 26. 14:37

※ C / C++을 이미 알고 있으나 개인적인 복습 및 공부를 위해 포스팅 하는 글이므로

C++에 대한 구체적인 정보를 담고 있지 않습니다.


 

▶ 함수 포인터

 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);
// 모던C++에선 이렇게도 표현한다

FUNC_TYPE* fn;

ㆍ *이 붙어있으니 포인터겠군... 타고 들어가니 함수가있네!


ㆍ 이게 함수포인터의 기초다.

 

int result = Add(1, 2);
cout << result << endl; 

//함수의 이름은 함수의 시작 주소를 가지고있다. 어셈블리에서 add로 주소를 넘겨주는 모습이다.

fn = Add; // 이게 함수포인터. fn이라는 놈으로 함수를 호출할 수 있다.

int result2 = fn(3, 4);
cout << result2 << endl;

int result3 = (*fn)(4, 4); //함수 포인터는 * 접근연산자를 붙여도 똑같은 함수주소
cout << result3 << endl;

 ※ 활용방법?
 ㆍ 위 fn의 주소를 Sub로만 바꿔주면 모든 부분을Sub로 바꾸지 않아도
 ㆍ 전부 다 Sub로 바뀐다!

ㆍ 내부적으론 어떻게 표기하든 같은 동작을 하고있다

 

 

※ 변수로만 보니 너무 심심하니 클래스와 함수로 테스트 해보자

class Item
{
public:
    Item() : _itemId(0), _rarity(0), _ownerId(0){}
public:
    int _itemId;    //아이템 구분
    int _rarity;    //희귀도
    int _ownerId;   //소지자
};

Item* FindItem(Item items[], int itemCount,int itemId /*동작(함수)*/)
{
    //안전체크... 일일히 하나하나 추가... 버그가 일어날 가능성이 높다
    for (int i = 0; i < itemCount; i++)
    {
        Item* item = &items[i];
        if (item->_itemId == itemId) 
        {
            return item;
        }
    }
    return nullptr;
}

ㆍ 이럴때 함수포인터를 사용하면 좋다. 매개변수로 동작 자체(함수)를 해주면 좋겠다..


ㆍ함수를 정의 해주고 함수포인터를 넘기는 방법으로 넘길 수 있다

 

typedef bool(ITEM_SELECTOR)(Item* item);

Item* FindItem(Item items[], int itemCount, int itemId, ITEM_SELECTOR* selector)
{
    //이렇게 작성하면 selector를 바꿔줘서 기능을 변경할 수 있겠다!
    for (int i = 0; i < itemCount; i++)
    {
        Item* item = &items[i];
        if (selector(item))
        {
            return item;
        }
    }
    return nullptr;
}


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

 

 


typedef int(*PFUNC)(int, int);
typedef int(Knight::* PMEMFUNC)(int, int);

 

ㆍ 클래스의 맴버함수를 함수포인터로 지정할땐 위와 같이 클래스를 지정해 줘야한다.

Knight k1;
PMEMFUNC mfn;
mfn = &Knight::GetHp;

(k1.*mfn)(1,1);

※ 맴버함수는 &나 * 등등 생략가능하던게 다 안된다.... 문법이 좀 복잡하다ㅜ

ㆍ 맴버함수 특성상 누구를 대상으로 하는지 명시해야 되기 때문에 그렇다

 

Kinght* k2 = new Knight(0;
(k2->*mfn)(1,1);
delete k2;

 

※ 알아만 두자ㅣ...

'C++프로그래밍 > 자료구조,알고리즘(추후확장)' 카테고리의 다른 글

vector의 동작 원리(size / capacity)  (0) 2024.09.28
콜백함수  (0) 2024.09.27
클래스 템플릿  (0) 2024.09.27
템플릿 기초 (함수템블릿)  (0) 2024.09.27
함수객체  (0) 2024.09.27