/**
stl을 좀 더 제대로 사용하고자 하니, functor가 필요하고, functor를 사용하고자 하니 operator가 필요 했다. 평소 operator를 잘 사용하지 않는 편에다가 'operator ()'라는 것이 익숙하지 않기에 그에 대한 테스트 코드를 작성 해 보았다.
*/
#include <iostream>
class __testOperator
{
public :
__testOperator()
{
std::cout << "Constructor was called" << std::endl;
}
~__testOperator()
{
}
void operator ()()
{
std::cout << "calls operator ()" << std::endl;
}
void operator ()(const __testOperator& oper)
{
std::cout << "calls operator (const __testOperator& oper)" << std::endl;
}
__testOperator& operator = (const __testOperator& oper)
{
std::cout << "calls operator =" << std::endl;
return *this;
}
__testOperator& operator += (const __testOperator& oper)
{
std::cout << "calls operator +=" << std::endl;
return *this;
}
bool operator == (const __testOperator& oper) {
std::cout << "calls operator ==" << std::endl;
return true;
}
};
간단한 클래스를 작성해 보았다. 위의 코드 중에서 다른 operator들은 평소에도 잘 써오고, 익숙한 녀석들이지만 void operator()()는 아직 나에겐 익숙하지 않은 operator다. 일반적으로 잘 사용되지는 않지만 (*)(void) 를 요청 할 때 사용되곤 한단다.
/**
한 가지 예로, stl의 generate_n 알고리즘을 사용할 때 사용된다.
generate_n 알고리즘 함수는, 그 세번째 인수로 함수명을 넘기면 함수포인터를, 클래스를 넘기면 클래스를 파라메터로 받는 generate()가 생성된다. 여기서 generate_n()이 내부적으로 호출하는 함수가 prototype을 (*)(void) 로 요청 하므로 generate에 사용되는 함수 객체의 operator() 함수는 반드시 (*)(void) 타입을 지켜야 된다.
보다 자세한 사항은 http://blog.naver.com/ziralist?Redirect=Log&logNo=7708214를 참조 하도록 하자.
*/
위의 코드가 어떻게 호출 되는지 main함수를 작성 해보도록 하자.
int main()
{
__testOperator testOperator;
testOperator();
testOperator(testOperator);
testOperator = testOperator;
testOperator += testOperator;
testOperator == testOperator;
return 0;
}
위와 같이 호출하면 아래와 같은 결과가 나온다. 특히 operator ()()와 operator()(const __testOperator& oper)의 결과에 주목하자. 결과를 살펴보면 operator()는 클래스 인스턴스를 함수 형태로 호출하는 모든 코드에 대해 반응하며 그 파라메터를 뒤 의(const __testOperator& oper) 부분에서 결정 한다는 것을 알 수 있다.
$ ./a.out
Constructor was called
calls operator ()
calls operator (const __testOperator& oper)
calls operator =
calls operator +=
calls operator ==
Constructor was called
calls operator ()
calls operator (const __testOperator& oper)
calls operator =
calls operator +=
calls operator ==