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 |