C++ ()연산자 오버로딩과 펑터(Functor)
- 프로그래밍/C/C++
- 2018. 10. 20.
C++ ()연산자 오버로딩과 펑터(Functor)
() 연산자를 오버로딩을 하게 되면 객체를 함수처럼 사용할 수 있게 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #include <iostream> using namespace std; class Point { int xpos, ypos; public : Point(int x = 0, int y = 0) : xpos(x), ypos(y) {} Point operator+(const Point &pos) const { return Point(xpos + pos.xpos, ypos + pos.ypos); } friend ostream& operator<<(ostream &os, const Point &pos); }; ostream& operator<<(ostream &os, const Point &pos) { os << '[' << pos.xpos << ", " << pos.ypos << ']' << endl; return os; } class Adder { public : int operator()(const int &n1, const int &n2) { return n1 + n2; } double operator()(const double &e1, const double &e2) { return e1 + e2; } Point operator()(const Point &pos1, const Point &pos2) { return pos1 + pos2; } }; int main() { Adder adder; cout << adder(1, 3) << endl; cout << adder(1.5, 3.7) << endl; cout << adder(Point(3, 4), Point(7, 9)); return 0; } | cs |
위와 같은 예제가 있다.
40행에서 class Adder을 선언해준다.
41행에서 출력을 해주는데 adder 클래스는 () 연산자를 오버로딩을 하고 있다. 24행으로 이동해서 n1 + n2 결과값을 반환해서 출력해주고 있다.
42행에서 1.5와 3.7을 넘겨주고 28행에서 e1 + e2 결과값을 반환해서 출력해주고 있다.
43행에서 Point클래스를 인자값으로 넘겨주고 있다. 32행으로 넘어가서 먼저 Point(7, 9)를 실행한다.
그럼 생성자가 호출이 되어 8행 생성자를 실행한다. 그럼 xpos = 7, ypos = 9 값이 들어간다.
그리고 Point(3, 4)가 실행이 되어 8행 생성자를 실행한다. 그럼 xpos = 3, ypos = 4 값이 들어간다.
그리고 pos1 + pos2 를 실행하는데 + 연산자를 Point 클래스에서 오버로딩을 했다.
그럼 다시 9행으로 넘어가서 xpos와 ypos를 각각 덧셈을 해준다. return Point 이니까 다시 한번 생성자를 호출하게 된다.
그럼 11행에서 생성한 Point는 xpos = 10, ypos = 13이 된다. 그리고 Point를 반환한다.
다시 43행으로 넘어와 << 연산자를 실행하는데 Point 클래스에서 << 연산자 오버로딩을 해줬다.
17행에서 출력을 해준다.
실행 과정은 이렇게 된다.
< 실행 결과 >
펑터란? 펑터의 위력은?
펑터란? : 위의 예제에서 Adder 클래스와 같이 함수처럼 동작하는 클래스를 '펑터(Functor)'라 한다.
그리고 '함수 오브젝트(Function Object)'라고도 불린다.
펑터는 함수 또는 객체의 동작방식에 유연함을 제공할 때 주로 사용된다.
말보다는 예제를 통해서 확인해보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | #include <iostream> using namespace std; class SortRule { public : virtual bool operator()(int num1, int num2) const = 0; }; class AscendingSort : public SortRule // 오름차순 { public : bool operator()(int num1, int num2) const { if (num1 > num2) return true; else return false; } }; class DescendingSort : public SortRule // 내림차순 { public : bool operator()(int num1, int num2) const { if (num1 < num2) return false; else return true; } }; class DataStorage { int *arr, idx; const int MAX_LEN; public : DataStorage(int arrlen) : idx(0), MAX_LEN(arrlen) { arr = new int[MAX_LEN]; } void AddData(int num) { if (MAX_LEN <= idx) { cout << "더 이상 저장이 불가능합니다." << endl; return; } arr[idx++] = num; } void ShowAllData() { for (int i = 0; i < idx; i++) cout << arr[i] << ' '; cout << endl; } void SortData(const SortRule &functor) { //버블정렬 사용 bool flag = true; for(int i =0; i<(idx - 1); i++) for (int j = 0; j < (idx - 1); j++) { flag = false; if (functor(arr[j], arr[j + 1])) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; flag = true; } } } }; int main() { DataStorage storage(5); storage.AddData(40); storage.AddData(30); storage.AddData(50); storage.AddData(20); storage.AddData(10); storage.SortData(AscendingSort()); storage.ShowAllData(); storage.SortData(DescendingSort()); storage.ShowAllData(); return 0; } | cs |