본문 바로가기

Cpp

함수 포인터

변수와 같이 함수도 선언한 후 실행하면 CPU에서 메모리에 주소가 할당된다.

함수의 이름은 함수의 주소를 담고 있다.

 

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

int main(void)
{
	cout << Add; // 함수의 주소를 출력한다.
	
	return 0;
}

 

함수 포인터 선언 형식

 

반환형 (*식별자)(매개변수);

함수 포인터의 시그니처는 주소를 받을 함수의 시그니처와 같아야 한다.

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

int main(void)
{
    int (*pf)(int, int); // (*f) 괄호로 감싸는 이유는 우선순위 때문이다. 
    					 // 괄호가 없으면 int*를 반환하는 pf 라는 함수로 인식 되기 때문
    pf = Add;
    
    cout << pf(10, 20); // 출력 30
    
	
	
	
	return 0;
}

 

함수 포인터의 상수화

 

int (*const pf)(int, int);

 

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

int Sum(int a, int b)
{
	a += b;
	return a;
}

int main(void)
{
    // int (*const pf)(int, int); // 에러. 포인터의 상수화 이므로 선언시 초기화
    
    int (*const pf)(int, int) = Add; // 함수 포인터의 const
    // pf = Sum; // 에러 포인터의 상수화 이므로 변경 불가능
    
    
	
	
	
	return 0;
}

 

함수 포인터의 배열

함수 포인터 선언시 식별자 뒤에 [n] 를 붙여준다. n 은 배열의 크기.

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

int Sum(int a, int b)
{
	a += b;
	return a;
}

int main(void)
{
    int (*pf[2])(int, int);
	
    pf[0] = Add;
    pf[1] = Sum;
    
	
	
	
	
	return 0;
}

 

매개변수 함수 포인터

 

함수 포인터가 주소를 가지고 있으니 함수의 매개변수로 설정 가능하다.

이때 매개변수의 함수 시그니처는 인자로 받을 함수 및 함수 포인터의 시그니처와 동일해야 한다.

 

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

int Show(int a, int b, int(*func)(int, int))
{	
	return func(a, b);
}

int main(void)
{
    int (*pf)(int, int);
	pf = Add;
    
    cout << Show(3, 4, pf); // 7을 출력
    cout << Show(3, 4, Add); // 7을 출력
	
	
	
	
	return 0;
}

Class 메소드를 함수 포인터에 넘겨주기

Class A
{
	
public:
	int Add(int a, int b)
    {
    	return a + b;
    }
}



int main(void)
{
	A a;
	int(A::*pf)(int, int) = &A::Add; // 함수 포인터 식별자와 함수 이름 앞에 해당 메소드를 포함하는
    								 // 클래스 이름과 범위 연산자를 붙여주어야한다.
    								 // & (주소 연산자)를 명시적으로 사용해야한다.
    // static 이 아닌 메소드는 thiscall 방식이므로
    // 함수 포인터라도 해당 메소드를 가지고 있는 클래스 객체가 있어야 한다.
    
    
	cout << (a.*pf)(3, 4) << endl;
	
	
	
	return 0;
}

 

 

Class 내의 static 메소드의 함수 포인터 접근

 

 

Class A
{
public:
	staic int Add(int a, int b)
    {
    	returin a + b;
    }


}



int main(void)
{
	int (*pf)(int, int) = &A::Add; // 클래스 이름으로 메소드 접근만 해준다.
    // static 메소드는 thiscall 방식이 아니기 때문에 객체가 필요 없다.
	
	cout << pf(3, 4) << endl;
	
	
	return 0;
}

 

클래스 내에 함수 포인터 선언

Class A
{
public:
	int (*pf)(int, int);
}

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

int main(void)
{
    A a;
	a.pf = Add;
    
    cout << a.pf(3, 4);



	return 0;
}

 

함수의 반환 값을 함수 포인터로 받기

기존 함수 포인터의 식별자 자리에 함수 이름을 선언한다.

반환 값을 함수의 주소로 한다.

 

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

int(*returnFunc(float x, float y))(int, int)
{
    cout << x << "  " << y << endl;
    return Add;
}


int main(void)
{
    cout << returnFunc(10.3f, 30.3f)(3, 4);
    // 10.3  30.3
    // 7  을 출력한다.




	return 0;
}

'Cpp' 카테고리의 다른 글

스마트 포인터  (0) 2023.06.13
얕은 복사 깊은 복사  (0) 2023.06.13
포인터  (0) 2023.06.12
STL MAP  (0) 2023.04.10
deque(double ended queue)  (0) 2023.04.10