728x90

함수는 메모리 영역(code, data, heap, stack) 중 code 영역에 있다.

함수 포인터

int Func(int a, int b);
 

위와 같이 함수가 선언되어 있을 때 실제 실행되는 것을 보면 결국 함수가 실행되는 시점에 특정 주소로 이동되어 다음 코드가 실행되는 것을 알 수 있다. 그러면 어떤 변수의 '주소'를 저장하는 것을 포인터라고 했으니, 함수의 '주소'를 저장하는 변수 또한 생성이 가능하다.

함수 포인터를 선언하는 방법은 아래와 같다.

// typedef int(Func)(int, int); -> 이렇게도 가능!
using Func = int(int, int); // 반환(인자, 인자)
Func* fn;

// using이나 typedef를 쓰지 않는 경우에는
int(*fn)(int, int);
 

이러면 이제 fn이라는 포인터는 함수의 주소를 저장할 수 있는 변수이고, 사용 방법은 다음과 같다.

// Add라는 함수가 있을 때
int Add(int a, int b) { return a + b; }

fn = Add; // Add 함수 주소를 저장, fn = &Add; 도 가능!
int ret = fn(1, 2); // ret = 3 호출!
// int ret = (*fn)(1, 2); 이렇게 실행해도 상관없다.
 

함수 객체

함수 처럼 동작하는 객체

함수 객체가 필요한 이유?

함수 포인터는 상태를 가질 수 없다. 즉, 값을 가질 수 없다. 여기서 상태(값)는 클래스 내부 변수 처럼 지속적으로 유지되는 값을 말한다.

사용 예제

class Functor
{
public:
	int operator()(int a, int b)
	{
		return _value + a + b;
	}

private:
	int _value = 1;
};

int main()
{
	Functor fn;
	fn(1, 2);
}
 

멤버 함수 포인터

위 함수 포인터는 전역 / 정적 함수만 담을 수 있다. 특정 class에 소속된 함수에 대한 포인터를 만드는 방법은 다음과 같다.

typedef [반환타입]([class]::*[함수이름])([인자]);
 

사용 예제

class Test
{
public:
	int TestInt(int a, int b)
	{
		return a + b;
	}
};

typedef int(Test::*TFunc)(int, int);

int main()
{
	Test t1;
	Test* t2 = new Test();

	TFunc fn;
	fn = &Test::TestInt;

	cout << (t1.*fn)(1, 2) << endl;
	cout << (t2->*fn)(1, 2) << endl;

	delete t2;
}
 
728x90

'C++ > C++ 기본' 카테고리의 다른 글

생성자 (Constructor)  (1) 2023.05.16
템플릿 기초  (0) 2023.05.12
캐스팅  (0) 2023.05.12
얕은 복사와 깊은 복사  (0) 2023.05.12

+ Recent posts