관리와 확장에 편리하다.
함수를 매개변수로 전달할 수 있다.(동작 전달)
int (*f2)(int, int);
typedef int(FUNC_TYPE)(int, int);
FUNC_TYPE *f1;
typedef int (*FUNC3)(int, int);
FUNC3 f3 = &Mul; // &생략할 수있다.
int를 반환하고 int 변수 두개를 매개변수로 받는 함수에 대한 포인터
멤버 함수에 대한 포인터의 형식에 몇 가지 다른 점이 있다.
typedef void(Num2::*PMFUNC)(FUNC);
PMFUNC pmf = &Num2::Show; //멤버함수 포인터는 &를 생략할 수 없다!!
PMFUNC pmf2 = &Num2::Oper;
(*num.*pmf)(f1); // 괄호를 꼭 해주어야한다. .* 연산자와 ->* 연산자
(num->*pmf2)(Mul); // 괄호를 꼭 해주어야한다. 멤버변수로 pmf2가 있는지 헷갈리기 때문이다.(컴파일러가)
함수 포인터는 동일한 시그니처의 함수만 가리킬 수 있지만 펑터는 ()연산자 오버로딩을 통해 다양한 함수 구현이 가능하다.
class ObFunc // 함수 객체(펑터) ()연산자 오버로딩을 통해 다양한 시그니처를 함수 포인터로 이용이 가능하다.
{
public:
int val;
float val2;
void operator()()
{
cout << "------펑터-------"<<endl;
}
int operator()(int a)
{
cout << "val: " << val << endl;
return a;
}
float operator()(float a)
{
cout << "val2: " << val2 << endl;
return a;
}
};
#include <iostream>
using namespace std;
typedef int(*FUNC)(int, int);
int Add(int a, int b)
{
cout << "더한다" << endl;
return a + b;
}
int Sub(int a, int b)
{
cout << "뺸다" << endl;
return a - b;
}
int Mul(int a, int b)
{
cout << "곱한다" << endl;
return a * b;
}
class Num2
{
public:
int num1;
int num2;
void Oper(FUNC f1)
{
cout<<f1(num1, num2)<<endl;
}
void Show(FUNC f2)
{
cout << "num1 : " << num1 << " , num2 :" << num2 << endl;
cout << "위 숫자들을 ";
f2(num1, num2);
}
};
class ObFunc // 함수 객체(펑터) ()연산자 오버로딩을 통해 다양한 시그니처를 함수 포인터로 이용이 가능하다.
{
public:
int val;
float val2;
void operator()()
{
cout << "------펑터-------"<<endl;
}
int operator()(int a)
{
cout << "val: " << val << endl;
return a;
}
float operator()(float a)
{
cout << "val2: " << val2 << endl;
return a;
}
};
int main()
{
typedef int(FUNC_TYPE)(int, int);
//using FUNC_TYPE=int(int, int) 모던 c++
FUNC_TYPE *f1;
f1 = Add;
int a = f1(1, 3);
cout <<"a: 1+3 = " << a << endl;
//타입정의 없이 바로
int (*f2)(int, int);
f2 = ⋐ //&붙이나 안붙이나 같다!!!
int b = f2(4, 2);
cout<< "b: 4-2 = " << b<< endl;
typedef int (*FUNC3)(int, int);
FUNC3 f3 = &Mul;
int c = f3(a, b);
cout << "c: a*b = " << c << endl;
int (*f4)(int, int);
f4 = Sub;
int d = (*f4)(c, b); // (*f4) 와 같이 호출하는 형식도 f2로 호출하는 것과 동일하다
cout << "d: c-b = " << d << endl;
cout <<"------여기부터 함수 포인터를 멤버함수의 매개변수로 하고 인자로 전달한 것-------" << endl;
Num2* num= new Num2;
num->num1 = 10;
num->num2 = 20;
num->Oper(Add);
num->Oper(Sub);
num->Oper(Mul);
//위의 것들은 정적, 전역함수만 가능하다.
//멤버함수는 어떻게 할까? 객체가 있어야 하기 때문에 다르다!ㅋ
typedef void(Num2::*PMFUNC)(FUNC);
PMFUNC pmf = &Num2::Show; //멤버함수 포인터는 &를 생략할 수 없다!!
PMFUNC pmf2 = &Num2::Oper;
(*num.*pmf)(f1); // 괄호를 꼭 해주어야한다. .* 연산자와 ->* 연산자
(num->*pmf2)(Mul); // 괄호를 꼭 해주어야한다. 멤버변수로 pmf2가 있는지 헷갈리기 때문이다.(컴파일러가)
ObFunc *obf= new ObFunc;
(*obf)();
obf->val = 10;
obf->val2 = 11.99f;
int ao = 4;
float bo=5.55f;
(*obf)(ao);
obf->operator()(bo);
ObFunc obf1;
obf1();
ObFunc();
}