📌 함수 포인터 활용

고속 처리

 

int main(void)
{	
	int instructions[1024] = { 0 };
	int pc = 0;

	while (instructions[pc])
	{
		switch (instructions[pc])
		{
		case 1: //add
			break;
		case 2: //sub
			break;
		case 3: //mul
			break;
		case 4: //div
			break;
		default:
			break;
		}

		pc++;
	}

	return 0;
}

 

위 코드는 instructions 배열 안에 있는 값에 따라 switch - case로 분기를 해 함수를 실행하는 구조문이다.

 

instructions 배열 안에 값이 1일 경우, add를 호출해 빠르게 처리할 수 있지만

만약 항목이 더 많아져서 배열안의 값이 1000일 경우 ( 물론 지금은 default로 처리 되지만 )

1000까지 비교해가면서 함수를 실행해야하기 때문에 속도가 느려진다.

 

이때 함수포인터 배열을 활용해 구조를 바꾸면 보다 빠르게 함수를 실행할 수 있어진다.

 

#include<stdio.h>

typedef struct MyParams {
	int param1;
	int param2;
	int param3;
} MYPARAMS;

int (*g_op_list[5])(MYPARAMS*); // 함수 포인터 배열

int add(MYPARAMS* pParam)
{
	return pParam->param1 + pParam->param2 + pParam->param3;
}

int sub(MYPARAMS* pParam)
{
	return pParam->param1 - pParam->param2 - pParam->param3;
}

int mul(MYPARAMS* pParam)
{
	return pParam->param1 * pParam->param2 * pParam->param3;
}

int div(MYPARAMS* pParam)
{
	return pParam->param1 / pParam->param2 / pParam->param3;
}

void init_op_list(void)
{
	g_op_list[1] = add;
	g_op_list[2] = sub;
	g_op_list[3] = mul;
	g_op_list[4] = div;
}

int main(void)
{
	init_op_list();
	int instructions[1024] = { 0 };
	int pc = 0;

	MYPARAMS param = { 0 };

	while (instructions[pc])
	{
		g_op_list[instructions[pc]](&param);

		pc++;
	}

	return 0;
}

 

위 처럼 switch - case 구문을 삭제하고 g_op_list 함수 포인터 배열을 활용해 직접적으로 해당 함수를 빠르게 호출해 줄 수 있다.

일반적인 함수를 저장하고, 다시 호출하는 방법은 위와 같다.

 

클래스에 있는 멤버 함수를 저장하고 호출할때는 어떻게 사용할까?

 

📌 클래스 함수 포인터 활용

정적

class Test
{
public:
    Test();
    ~Test();
private:
    void (Test::*Handler[5])(int a, int b);
public:
    void Add(int a, int b);
}

 

클래스 안의 멤버 함수는 this 포인터를 받아야 하기 때문에 호출 방식이 일반 함수와는 다르다.

위의 Handler는 일반 함수가 아니라 Test 객체의 멤버 함수를 저장할 수 있다고 선언한다는 의미다.

 

Handler에 Test 클래스의 멤버함수를 저장하려면 다음과 같이 하면 된다.

packetProc[1] = &Test::int;

 

위와 같이 멤버 함수를 저장하고, 호출할때는

(this->*Handler[1])(a, b);

 

이처럼 호출하면 된다.

 

위 예시는 5개로 크기가 지정되어있는데, 동적으로 만드려면 어떻게 해야할까?

 

동적

class Test
{
public:
    Test();
    ~Test();
private:
    void (Test::**Handler)(int a, int b);
public:
    void Add(int a, int b);
}

 

동적 할당 받기

Handler = new void(Test::**)(int, int)[count];
memset(Handler, 0, sizeof(void (Test::**)(int, int)) * count);

 

소멸자에서 해제

Test::~Test()
{
    delete[] Handler;
    Handler = nullptr
}

 

멤버함수를 저장하고, 호출하는 방식은 정적 방식과 동일하다.

+ Recent posts