Game !
C++

[C++] 함수 포인터2022. 5. 6. 06:10

 

 


함수 포인터

함수의 주소값을 저장하는 포인터 (함수의 시작 주소를 가리킨다)


함수 :
프로그램(exe 파일)이 실행될 때, 우리가 소스파일에 정의한 모든 함수가 메인 메모리(프로그램이 실행되면서 할당받은 메모리)에 올라간다. 
이때. 우리가 작성한 함수이름은 함수의 시작 주소를 가리키는 포인터가 되는데, 이 포인터가 가리키는 주소가 변경되면 안되니까.. 포인터 상수로 함수의 시작 주소를 가리키게 된다.
이것을 함수 포인터 라고 부른다.

포인터 상수 : const ptr 
포인터를 상수로 처리했다 는 의미이다. ---> "포인터를 상수로" 라고 생각하면 쉽다.

cf.
상수 포인터 : ptr
상수를 가리키는 포인터 라는 의미이다. ---> "상수를 가리키는 포인터" 라고 생각하면 쉽다.

 

 


① 함수 포인터 선언 문법

void (*FuncPtrName)(int, int)
---> 반환값과 매개변수 타입이 동일한 함수만 호출 가능

FuncPtrName : 함수 포인터의 이름


문법상 괄호와 포인터 표기는 필수!

- 괄호
예를 들어, int (*FuncPtrName) ( ); 에서.. 괄호는 제거하게 되면
int* FuncPtrName( ); 이렇게 된다. 이것은 int형 포인터를 반환하는 함수 의 전방선언으로 해석되기 때문에, 함수 포인터를 선언할 때는 문법상 괄호는 꼭 넣어줘야 한다.

- 포인터 :
함수 포인터도 포인터니까.. 포인터 변수 선언하듯 이름 앞에 붙여준다.


② 상수 함수 포인터 선언 문법

상수 함수 포인터 : 함수 포인터가 가리키는 주소를 변경할 수 없도록 상수화 처리한 것

void (*const FuncPtrName)(int, int);

포인터 뒤에 const 를 붙인다.
이 함수 포인터는 초기화 외에는 주소값 변경이 불가능하다.

 

 


함수 포인터 사용 ① : 기본

double Add( double left, double right )
{
     return left + right ;
}

void main( )
{
     // double (*FuncPtrCalc)(double, double) ---> 자체가 변수 선언이다.
     // 변수 이름은 함수 포인터가 된다.

     double (*FuncPtrCalc)(double, double) = NULL;
     FuncPtrCalc = Add;

     double value1 = FuncPtrCalc( 1.234, 3.141592 );
     double value2 = GetCalcTypeValue( Add, 1.234, 3.141592 );
}

double GetCalcTypeValue( double (*InFuncPtr)(double, double), double left, double right )
{
     return InFuncPtr( left, right );
}

해당 방식은 가독성이 떨어져서 잘 사용하지 않는다.

함수 포인터 사용 ② : typedef 로 일반 함수처럼 보이게 만든다

typedef double (*FuncPtrCalc)(double, double);

double Add( double left, double right )
{
     return left + right ;
}

void main( )
{
     FuncPtrCalc = Add;

     double value1 = FuncPtrCalc( 1.234, 3.141592 );
     double value2 = GetCalcTypeValue( Add, 1.234, 3.141592 );
}

double GetCalcTypeValue( FuncPtrCalc funcCalc, double left, double right )
{
     return funcCalc( left, right );
}

가독성을 위해 가장 일반적으로 사용한다.

함수 포인터 사용 ③ : 가독성을 높이기 위해 C++11 에 추가된 방법

ⓐ using 을 사용한 방법

using FuncPtrCalc = double ( * )(double, double);

double Add( double left, double right )
{
     return left + right ;
}

void main( )
{
     FuncPtrCalc = Add;

    double value1 = FuncPtrCalc( 1.234, 3.141592 );
    double value2 = GetCalcTypeValue( Add, 1.234, 3.141592 );
}

double GetCalcTypeValue( FuncPtrCalc funcCalc, double left, double right )
{
    return funcCalc( left, right );
}



ⓑ std::function 키워드를 사용한 방법
단, #include <functional> 을 추가해줘야 사용가능하다.

double Add( double left, double right )
{
     return left + right ;
}

void main( )
{
     std::function<double (double, double)> FuncPtrCalc;

     FuncPtrCalc = Add;

     double value1 = FuncPtrCalc( 1.234, 3.141592 );
     double value2 = GetCalcTypeValue( Add, 1.234, 3.141592 );
}

double GetCalcTypeValue( std::function<double (double, double)> funcCalc, double left, double right)
{
     return funcCalc( left, right );
}

 

 

 

 

 

 

 

'C++' 카테고리의 다른 글

[C++] 코드 위치나 정보를 받아오는 매크로 들  (0) 2022.05.08
[C++] interface  (0) 2022.05.06
[C++] 문법 - 범위 지정 연산자  (0) 2022.04.01
C++ for_each 함수  (0) 2018.03.21
[C++] 중첩 클래스 사용 이유  (0) 2018.01.10