본문 바로가기
C C++ - STL

STL - 11 Function Object (함수 - 객체)

by violetoz 2014. 2. 13.
[STL-11] Function Object (함수-객체)|STL을 배우자
2005.02.13 15:47

정말 오랜만입니다..

이번에는 함수-객체에 대하여 간단히 정리하였습니다. 뭐, 다 그렇지만 원체 넓은 범위의 내용을 필요로 하기 때문에 간단한 사용 방법과 형태에 대하여 기록하였습니다.

 

처음 함수-객체의 사용 형태를 보는 사람들은 대부분 이런 형태가 생소하게 느껴질 겁니다함수 객체는 제네릭 알고리즘을 잘 사용하기 위해서는 절대적으로 필요합니다조건자(predicate)로 사용할 수 있으며함수 어댑터(Function Adapter)로도 사용됩니다이러한 내용까지 모두 거론하기엔 양이 많으니 간단하게 함수-객체가 무엇인지 한 번 보고간단한 예제를 보도록 하겠습니다.

C++ Standard Library에서 함수-객체에 대하여 다음과 같이 설명하고 있습니다.

 

함수-객체는 완전 추상화와 제네릭 프로그래밍 예이다함수처럼 행동하는 모든 것을 함수라고 말할 수 있다따라서 함수처럼 행동하는 객체를 정의한다면 이것을 함수처럼 사용할 수 있다.

함수-객체는 () 연산자를 정의한 객체이다.

FunctionObjectType fo;

...

fo(...);

fo()의 코드는 함수 fo()를 호출하는 것이 아니라 함수-객체인 fo의 () 연산자를 호출한다.

 

함수-객체를 처음 사용하는 사용자들은 기존의 함수에 비해서 좀 더 복잡한 방법으로 함수-객체를 정의한다고 생각할 수 있다다음과 같이 함수 구문 안에 모든 함수에 대한 내용을 코딩하는 것이 아니라,

void fo()

{

                  statements

}

함수-객체 클래스의 () 연산자 안에 코딩해야만 한다.

class FunctionObjectType {

public:

                  void operator() (){

                                   statements

                  }

};

이런 방식의 코딩은 좀 더 복잡하지만 다음과 같은 3가지 장점을 가지고 있다.

1.       함수-객체는 상태를 가질 수 있기 때문에 좀 더 영리하다고 생각할 수 있다사용자는 같은 함수-객체에 대해서 동시에 다른 상태를 가질 수 있다는 것이다이러한 점은 기존의 함수로는 불가능하였다.

2.       각각의 함수-객체는 자신의 타입을 가진다그러므로 사용자는 이 함수-객체의 타입을 템플릿의 인자로 제공할 수 있다이는 곧 다른 함수-객체를 가지는 컨테이너를 가질 수 있다는 의미이다.

3.       함수-객체는 함수 포인터 보다 빠르다.

 

몇 가지 예를 보면 좀 더 이 글에 대한 이해가 쉬울 것 같습니다.

컨테이너의 모든 원소에 특정한 값을 더하는 기능을 만든다고 하면 일반적인 함수나 템플릿 함수로 할 수 있습니다.

아래 내용은 list를 double type으로 선언하고각 요소들의 값에 5를 더합니다.

 1  /*---------------------------------------------------------------
 2      File name   :   function_object.cpp
 3      Creater     :   Jeong-il Ahn(raon_pgm@naver.com)
 4      Date        :   2005. 02. 11.
 5      Subject     :   Function Object
 6      Purpose     :   함수-객체에 대하여 이해
 7      Update Date :   2005. 02. 11.
 8      Version     :   1.00.00
 9  ----------------------------------------------------------------*/
10
11  #include <iostream>
12  #include <cstdlib>
13  #include <algorithm>
14  #include <list>
15
16  //  Print Container Element
17  template <typename T> inline void DataPrint (const T& coll, const char* str="")
18  {
19      typename T::const_iterator pos;
20      std::cout << str;
21      for (pos=coll.begin(); pos!=coll.end(); ++pos)
22          std::cout << *pos << ' ';
23      std::cout << std::endl;
24  }
25
26  // Template function
27  template <typename T>
28  void ValueAdd(T & e)
29  {
30      e += 5;
31  }
32
33  int main(int argc, char **argv)
34  {
35      using namespace std;
36      list<double> nList;
37
38      for( int i = 0 ; i < 10 ; ++i )
39          nList.push_back(i+0.1);
40
41      DataPrint (nList, "Befor adding each element : ");
42      for_each (nList.begin(), nList.end(), ValueAdd<double>);
43      DataPrint (nList, "After adding each element : ");
44
45      return EXIT_SUCCESS;
46  }

result

$ function_object1

Befor adding each element : 0.1 1.1 2.1 3.1 4.1 5.1 6.1 7.1 8.1 9.1

After adding each element : 5.1 6.1 7.1 8.1 9.1 10.1 11.1 12.1 13.1 14.1

 

하지만 컴파일 타임이 아닌 런타임에 이 값을 변경하고 싶다면 위의 방식으로는 불가능합니다함수가 불려지기 전에 이 함수에 값을 전달해야 하는데 이렇게 하려면 하나의 함수로는 불가능합니다그리고 상태를 보존하려면 static 변수를 사용하거나 같은 함수지만 다른 상태를 가져야 하는 일이 생깁니다.

아래 예는 Template 함수-객체를 선언하여 입력되는 자료 형에 맞춰 컨테이너 요소의 각 값에 입력 값을 더합니다.

 1  /*---------------------------------------------------------------
 2      File name   :   function_object2.cpp
 3      Creater     :   Jeong-il Ahn(raon_pgm@naver.com)
 4      Date        :   2005. 02. 11.
 5      Subject     :   Function Object
 6      Purpose     :   함수-객체에 대하여 이해
 7      Update Date :   2005. 02. 11.
 8      Version     :   1.00.00
 9  ----------------------------------------------------------------*/
10
11  #include <iostream>
12  #include <cstdlib>
13  #include <algorithm>
14  #include <list>
15
16  //  Print Container Element
17  template <typename T> inline void DataPrint (const T& coll, const char* str="")
18  {
19      typename T::const_iterator pos;
20      std::cout << str;
21      for (pos=coll.begin(); pos!=coll.end(); ++pos)
22          std::cout << *pos << ' ';
23      std::cout << std::endl;
24  }
25
26  // Template function object
27  template <typename T>
28  class ValueAdd
29  {
30  private:
31      T value;
32  public:
33      //초기값을 갖는 생성자
34      ValueAdd(const T &v) : value(v){}
35      //()를 overloading하여 각 원소에 value를 더함
36      void operator() (T & elem) const {
37          elem += value;
38      }
39  };
40
41  int main(int argc, char **argv)
42  {
43      using namespace std;
44      list<double> nList;
45
46      double dblInvalue = 0.;
47      cout << "Enter the number (floating type) : ";
48      cin >> dblInvalue;
49
50      for( int i = 0 ; i < 10 ; ++i )
51          nList.push_back(i);
52
53      DataPrint (nList, "Befor adding each element : ");
54      // 각 원소에 입력된 값을 더함.
55      for_each (nList.begin(), nList.end(), ValueAdd<double>(dblInvalue));
56
57      DataPrint (nList, "After adding each element : ");
58
59      return EXIT_SUCCESS;
60  }

result

$ function_object2

Enter the number (floating type) : 3.25

Befor adding each element : 0 1 2 3 4 5 6 7 8 9

After adding each element : 3.25 4.25 5.25 6.25 7.25 8.25 9.25 10.25 11.25 12.25

 

함수-객체의 응용 범위는 상당히 넓습니다위의 예는 극히 간단히 형태 입니다.

미리 정의된 함수-객체가 있습니다. <functional>에 정의되어 있는데 아래 사이트를 참고하시기 바랍니다.

 

http://www.dinkumware.com/manuals/reader.aspx?b=p/&h=functio2.html

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcstdlib/html/vclrf_functional_header.asp

http://www.sgi.com/tech/stl/functors.html


'C C++ - STL' 카테고리의 다른 글

STL - 13 allocator  (0) 2014.02.13
STL - 12 auto_ptr  (0) 2014.02.13
STL - 10 Vector Container 구현  (0) 2014.02.13
STL - 9 find, find_if  (0) 2014.02.13
STL - 8 Vector 라이브러리  (0) 2014.02.13