재능 가운데 가장 소중한 재능은 한 마디면 될 때 두 마디 말하지 않는 재주. ―토머스 제퍼슨
1 시작하며 #
클래스를 사용할 때 새로운 클래스에 대한 이미 존재하는 연산자의 의미를 새롭게 정의하는 것이 가능하다. (이것을 가리켜서 연산자 오버로딩이라고 한다.) 이것들은 맴버함수나 friend 함수로써 정의된다. 그러나, 연산자 오버로딩을 그저 무조껀 있으니까...하면서 사용하거나 좀더 괜찮은 트릭같은 형태로 사용하는 것은 별로 좋지 않다. 이것은 프로그램 코드를 좀더 깔끔하게 하는데에만 사용하는 것이 권장된다. 만일 = 연산자를 곱셈이 되도록 만든다면 사용하는 사람은 혼란이 올 수도 있을 것이다. ^^;
2 왜 연산자들을 오버로딩(재정의)하는가? #
새로운 클래스를 작성할 때, 여러분이 정의한 연산자들은 메소드(함수)의 형태로써 작성된다. 예를 들자면, 수학에서의 벡터로부터 각 요소를 얻고자 할때, 여러분은 다음과 같이 함수를 정의할 지도 모른다.
x = v.at(25);
일반적으로 연산자를 오버로딩하는 이유는 ==, [], + 등등의 표면적인 의미를 사용하여 프로그램의 가독성을 높이는데 있다. [] 연산자를 오버로딩함으로써 위의 예제를 다음과 같이 고칠 수 있게 된다.
x = v[25];
특정 클래스나 탬플릿에서 특별한 연산자를 내부적으로 사용하지 않는다면 연산자 오버로딩은 반드시 엄격하게 필요한 문법은 아니다. 그러나 반드시 필요한 경우가 가끔 있을 수 있다. (STL이 그 예이다. STL/list간단사용법을 참조해라.)
자바는 연산자 오버로딩을 지원하지 않는다. 그 이유는 연산자 오버로딩을 남용할 경우, 깔끔함보다는 혼란을 야기할 수 있기 때문이다. 프로그램의 가독성을 높여줄 것인가 혹은 혼란을 가중시킬 것인가는 이것을 어떻게 잘 사용하느냐에 달려있음을 명심하기 바란다.
3 어떠한 연산자가 재정의 될 수 있는가? #
비록 그 우선순위는 바꿀 수 없다 할지라도, 대부분의 모든 연산자가 재정의 될 수 있다. 재정의될 수 없는 연산자는 ::, sizeof, ?:, .(점 연산자)를 들 수 있다. new 연산자를 생성하는 것은 불가능하며, 단지 오버로딩만이 가능하다. + 연산자를 오버로딩하는 것은 +=까지도 자동으로 오버로딩되는 것은 아니며, 각각을 따로 오버로딩 해주어야만 한다.
=, [], {}, -> 연산자들은 반드시 맴버함수로 표현해야 한다. ++, --는 특별한 취급을 받는다. The are some special issues with overloading assignment (=).
4 예제 - Point 클래스를 위한 + 연산자를 정의하기 #
Point 클래스를 사용하기 위해, 다음과 같이 정의될 수 있다 :
//=== Point.h =============================
Point operator+(Point p) const;
//=== Point.cpp ===========================
Point Point::operator+(Point p) const {
return Point(x+p.x, y+p.y);
}
//=== myprogram.cpp ============================ Point a(10, 20); Point b(1, 2); Point c = a + b;
5 "operator" 키워드로 시작하는 함수를 정의하기 #
오버로딩할 연산자에 대한 함수를 정의할 때 반드시 "operator"키워드와 오버로딩할 연산자를 붙여서 사용한다는 것을 알아두자. "operator" 키워드와 연산자 기호 사이에는 공백이 있을 수 있지만 반드시 같이 사용해야만 한다. (operator+, operator<, operator*등등의 표현이 있을 수 있다)무슨 뜻이냐면, 다음과 같이 사용하는 것은 틀린 표현이다.
// +와 operator가 순서가 바뀌어 있다.
Point Point::+ operator(Point p) const {
return Point(x+p.x, y+p.y);
}
6 오버로딩 가능한 연산자들은 무엇이 있는가? #
다음과 같다.
+ - * / = < > += -= *= /= << >> <<= >>= == != <= >= ++ -- % & ^ ! | ~ &= ^= |= && || %= [] () new delete
7 연산자들에 따른 오버로딩 함수 선언 형식 #
다음 표를 참조하라. (@는 연산자를 나타낸다. ()연산자의 경우 ... 처리한 이유는 선언할 때 인자의 개수를 정할 수 있다는 의미이다. printf()의 인자같은 것이라고 생각하면 되겠다.)
| 구문 | 연산자 | 맴버함수일 경우 | 전역함수일 경우 |
| @a | - * & ! ~ ++ -- | A::operator@() | operator@(A) |
| a@ | ++ -- | A::operator@(int) | operator@(A, int) |
| a@b | - * / % ^ & | < > == != <= >= << >> && |*2(OR비교연산자) , | A::operator@(B) | operator@(A, ![]() |
| a@b | = += -= *= /= %= ^= &= |= <<= >>= [ ] | A::operator@(B) | 사용할수없음 |
| a(b, c...) | () | A::operator()(B, C...) | 사용할수없음 |
| a->b | -> | A::operator->() | 사용할수없음 |









![[http]](/wiki/imgs/http.png)
.png)
