함수 포인터
함수도 다른 변수들처럼 자신의 [주소]를 가지고 있습니다.
이 함수의 주소를 포인터 변수에 저장하여 사용할 수 있는 것을 함수 포인터 라고 합니다.
[ 함수 포인터 예제 ]
int (*f)(int, int); = 리턴타입(*포인터이름)(매개변수1, 매개변수2 / 단,매개변수없을시 () 또는 void);
위의 형태로 선언 할 수 있습니다.
위처럼 선언하였을때 함수의 주소값을 저장할 수 있는 [ f ] 의 이름을 가진 함수포인터가 만들어집니다.
[ f ] 라는 이름의 포인터 안에는 함수의 [주소]를 저장 하여 사용 합니다.
[ 함수 포인터 사용 예제 ]
#include <iostream>
using namespace std;
int add(int a, int b)
{
return ( a + b );
}
int main(void)
{
int (*f)(int, int); // 함수포인터 생성
f = add; // 생성한 f 함수포인터에 add 함수의 주소를 넣습니다.
cout << f(11,22) << endl; // add(11 + 22)실행 33출력
return 0;
}
위처럼 만들어져 있는 함수를 함수포인터에 넣어주고 함수포인터로 함수를 실행할 수 있습니다.
매개 변수로 사용 가능한 함수 포인터
함수 포인터는 다른 변수처럼 매개 변수로 사용할 수 있습니다.
[ 매개변수로 함수 포인터 사용 예제 ]
#include <iostream>
using namespace std;
int add(int a, int b)
{
return ( a + b );
}
void print_odd(int a, int b, int (*f)(int, int)) // 매개변수1, 매개변수2, 매개변수3(함수포인터)
{
int ret = f(a, b); // 임시변수에 매개변수 대입
if (ret % 2 == 1) // 함수실행결과가 홀수인조건
cout << ret << endl;
else
cout << "짝수 입니다."<< endl;
}
int main(void)
{
print_odd(2, 4, add); // 짝수입니다 출력
print_odd(1, 4, add); // 홀수조건이므로 결과로 5 출력
return 0;
}
함수 포인터의 const ( 상수 )
함수포인터도 다른 변수들처럼 상수 선언이 가능 합니다.
[ 상수선언으로 함수 포인터 사용 예제 ]
#include <iostream>
using namespace std;
int add(int a, int b)
{
return ( a + b );
}
int main(void)
{
int (*const f)(int, int) = add; // const 선언으로 상수화
cout << f(1,2) << endl; // 출력결과 3
return 0;
}
class 멤버함수의 함수 포인터
클래스의 멤버함수도 함수 포인터로 사용이 가능합니다.
단, 클래스 내부의 멤버함수는 꼭 [객체]를 통해서만 접근이 가능합니다.
또한 함수포인터의 선언은 해당 클래스의 [범위]내에있는 함수포인터라고 명시한후 사용 가능합니다.
#include <iostream>
using namespace std;
class Test // 클래스 선언
{
public:
int add(int a, int b) // 클래스 내부에 위치한 함수 add
{
return (a + b); // 매개변수 두개를 더해서 반환
}
};
int main(void)
{
Test test; // Test 클래스를 인스턴스화 시켜서 test 객체를 생성 합니다.
int (Test::*f)(int, int) = &Test::add;
// 함수 포인터 [ f ] 는 Test의 멤버함수를 사용하기위해서 Test::(범위접근) 을 명시합니다.
// 함수의 주소 또한 Test의 멤버함수임을 명시해 주고 [ &Test:: ]
// 위처럼 꼭 & 참조 연산자를 통해서 주소를 가져와야 합니다.
cout << (test.*f)(1,2) << endl; // test 객체의 함수 add 호출 출력 : 3
// 함수포인터는 생성된 클래스 객체를 통해서 호출이 가능합니다.
// 만일 클래스 멤버함수 내에서 함수포인터를 사용한다면 그때는 [ this ] 를 통해서 접근합니다.
// 접근 멤버 포인터 연산자인 [ .* ] 혹은 [ ->* ] 연산자로 접근해야 합니다.
return 0;
}
static(정적)을 이용한 멤버함수 접근
class 에서 멤버함수에 static 을 사용한다면 class 의 이름 으로 해당 함수에 접근이 가능하며,
어떤 특정 객체에 귀속 되지 않습니다.
때문에 class 의 이름을 통해서 접근만 해준다면 일반 함수포인터와 동일하게 사용이 가능합니다.
#include <iostream>
using namespace std;
class Test1 // 1클래스 생성
{
public:
static int add(int a, int b) // [+ 함수]
{
return (a + b);
}
};
class Test2 // 2클래스 생성
{
public:
static int sub(int a, int b) // [- 함수]
{
return (a - b);
}
};
class Test3 // 3클래스 생성
{
public:
static int div(int a, int b) // [/ 함수]
{
return (a / b);
}
};
class Test4 // 4클래스 생성
{
public:
static int mul(int a, int b) // [* 함수]
{
return (a * b);
}
};
int main(void)
{
//함수 포인터의 배열을 선언 합니다.
//선언 후 class 의 이름을 통하여 함수의 주소를 저장 합니다.
int (*f[4])(int, int) = {
&Test1::add,
&Test2::sub,
&Test3::div,
&Test4::mul
};
for(int i = 0, i < 4; i++)
{
cout << f[i](1,2) << endl; // 함수포인터처럼 출력됩니다.
// 함수 순서대로 의결과 3, -1, 0, 2 출력
}
return 0;
}
'공부' 카테고리의 다른 글
[자료구조] SIMD (Single Instruction Multiple Data) (0) | 2023.06.19 |
---|---|
[C++] 람다 표현식 (Lambda Expression) (0) | 2023.05.27 |
[C++/DX11] 3D 가위바위보 (1) | 2023.05.21 |
[C++/DX11] 리소스매니저클래스, XML파일 저장&불러오기 (0) | 2023.05.18 |
[C++/DX11] Yaw Pitch Roll(요,피치,롤), Gimbal Lock(짐벌락), Quaternion(쿼터니언) (2) | 2023.05.16 |
댓글