C++ Function Object (함수 객체)를 알아보자
Lamda (람다) 포스팅을 하기 위해 공부하던 중,,
이상하게 글이 안써졌다. 기초 없이 사용할려고 하니까 그런것 같아서
함수 객체에 대해 먼저 공부를 해보려고 한다
1. 함수 호출 연산자
함수 객체를 사용해보기 전에, 함수 호출 연산자를 봐보겠다
아주아주 간단한 예시를 들어보겠다
#include <iostream>
#include <algorithm>
using namespace std;
int myPlus(int num1, int num2)
{
return num1+num2;
}
int main(void)
{
int num1 = 10;
int num2 = 20;
cout << myPlus(num1, num2) << endl;
return 0;
}
myPlus라는 함수에 파라미터 값으로 int 형 변수를 넣어 덧셈을 하는 예시이다
이렇게 우리는 함수를 사용시에 아래 형식으로 사용한다
int func_name(int num1..)
사용하는 것들은 함수 반환형, 함수 이름, 파라미터 그리고 함수 호출 연산자인 () 이다.
보통 괄호라고 부르는 "( )" 를 함수 호출 연산자라고 한다
직역하면 함수를 부르는~~ 연산자(operator) 정도가 되겠다
함수 호출 연산자는 함수 객체와 operator 사용에 특히 유용하게 사용할 수 있다
언젠가 들어봤을 연산자 오버로딩에서, +/-/<<.. 이런 연산자에 대해
C++에서는 오버로딩을 사용해서! 자기만의 연산자 함수를 사용할 수 있다
예를 들어, operator+() 요런 식으로.
()라는 연산자도 operator()로 오버로딩해서 사용할 수 있는거다 → () 는 operator()와 같다는 말
2. 함수 객체
그러면 함수 호출 연산자와 함수 객체는 뭔 상관인가?를 알아보겠다
함수 객체를 사용해서, 위의 예제처럼 덧셈을 하는 예시를 먼저 보자
class MyPlus
{
public:
int operator()(int num1_, int num2_)
{
return num1_ + num2_;
}
};
int main(void)
{
int num1 = 10;
int num2 = 20;
MyPlus funcP;
cout << funcP(num1, num2) << endl;
return 0;
}
MyPlus라는 클래스 안의 내부 함수로 operator()라는 함수를 만들어보았다
funcP(num1, num2)
요 부분을 주의 깊게 보자
MyPlus의 객체인 funcP와 함수 호출 연산자인 ()로
MyPlus 클래스 내부의 operator()라는 함수를 사용하는 것을 볼 수 있다
위의 예제에서, myPlus() 함수와 사용법이 다르지 않게 느껴지지 않는가,,?
클래스의 객체를 마치 함수처럼 사용할 수 있는데, 이것을 함수 객체 라고 부른다
operator() 연산자를 오버로딩하였기 때문에, .operator() 가 생략된 것도 알아가자
funcP(num1, num2);
funcP.operator()(num1, num2);
근데, 함수 객체를 사용해서 함수 호출 연산자로 함수를 오버로딩해서
사용하는 것 까지는 알겠는데, 굳이? 라는 생각이 든다
오히려 일반 함수보다 더 복잡한거 아닙니까 스앵님,,
아래 예시를 보면 생각이 달라질 수 있다
int mySum(int num1)
{
int sumRet = 0;
sumRet += num1;
return sumRet;
}
int main(void)
{
int num1 = 10;
int num2 = 20;
/* 1. 함수 이용 */
auto ret = mySum(num1);
cout << ret << endl;
ret = mySum(num2);
cout << ret << endl;
/* 10 */
/* 20 */
return 0;
}
mySum이라는 함수를 사용해서, num1도 더하고~ num2도 더하고 싶었으나
글로벌 함수가 아닌이상, 지역변수에 더한 결과를 누적할 수 없으셈
하지만, 클래스 멤버 변수에 저장해 놓으면? 누적된 값을 사용 가능하다
class MySum
{
int sumRet = 0;
public:
int operator()(int num1_)
{
sumRet += num1_;
return sumRet;
}
};
int main(void)
{
int num1 = 10;
int num2 = 20;
/* 2. 함수 객체 이용 */
MySum sumP;
ret = sumP(num1);
cout << ret << endl;
ret = sumP(num2);
cout << ret << endl;
/* 10 */
/* 30 */
return 0;
}
MySum이라는 클래스의 객체인 sumP를 사용하여, 내부의 operator() 함수를 ()로 오버로딩하여
클래스의 멤버 변수인 sumRet에 더한 값을 누적할 수 있다 이 말이다
정리하자면, 함수 객체의 장점은 다음과 같다
- 클래스의 특성을 사용하여 상태 값을 알 수 있음
- 일반 함수보다 속도가 더 빠름 → 함수의 인라인화 ( 다음 포스팅에서 다룰 예정 )
자신의 쓰임새에 맞게 알맞게 사용해보자
다음 포스팅에서는 함수의 인라인과 람다를 공부해서 정리해야겠다
용어 정리도 필요할 것 같음