{{위키데이터 속성 추적}}
'''연산자 오버로딩'''(operator overloading)은 객체 지향 [[컴퓨터 프로그래밍]]에서 [[다형성]]의 특정 경우로 다른 연산자들이 함수 인자를 통해서 구현을 할 때를 말한다. 연산자 오버로딩은 일반적으로 언어, 프로그래머, 또는 두 가지 모두에 의해 정의된다.

[[연산자 (프로그래밍)|연산자]] 오버로딩은 프로그램 개발자가 "가까운 목표 범위(closer to the target domain)" 표기법을 사용할 수 있고<ref>{{웹 인용 | title=C++ FAQ Lite: What are the benefits of operator overloading? | url=http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.2 | accessdate=August 2010 | year=2010 | month=June | 보존url=https://web.archive.org/web/20110814105309/http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.2 | 보존날짜=2011년 8월 14일 | url-status=dead }}</ref> 사용자 정의 타입과 비슷한 수준을 허락하기 때문에 언어에 내장된 형식으로 구문을 지원한다. 그것은 쉽게 함수 호출을 사용하여 모방할 수 있다; 예를 들어, 정수 a, b, c를 생각하면:

 a + b * c

연산자 오버로딩을 지원하는 언어에서, '*' 연산자는 '+' [[연산의 우선순위|우선 순위]]보다 높고, 이것은 효과적으로 좀 더 간결한 작성 방법일 것이다:

 add (a, multiply (b,c))

== 예시 ==
사용자 정의 유형의 "Time"에 추가 허용하는 연산자 오버로딩의 예시 (C++에서):

<syntaxhighlight lang="cpp">
 Time operator+(const Time& lhs, const Time& rhs) {
     Time temp = lhs;
     temp.seconds += rhs.seconds;
     if (temp.seconds >= 60) {
         temp.seconds -= 60;
         temp.minutes++;
     }
     temp.minutes += rhs.minutes;
     if (temp.minutes >= 60) {
         temp.minutes -= 60;
         temp.hours++;
     }
     temp.hours += rhs.hours;
     return temp;
 }
</syntaxhighlight>

덧셈은 왼쪽과 오른쪽 피연산자를 의미하는 이항 연산이다. C++에서, 전달되는 인자는 피연산자이며, 임시 개체가 반환 값이다.

연산자는 또한 클래스 메서드를 정의할 수 있으며, 숨겨진 <code>this</code> 인수로 <code>lhs</code>를 대체한다. 그러나 이것은 왼쪽 피연산자 타입 <code>Time</code>의 효과와 <code>this</code>는 수정 가능하게 될 수 있는 ''lvalue(왼쪽 값)''을 추정한다.

<syntaxhighlight lang="cpp">
 Time Time::operator+(const Time& rhs) const {
     Time temp = *this;  /* 'this' 값 복사, 이것은 수정되지 않는다. */
     temp.seconds += rhs.seconds;
     if (temp.seconds >= 60) {
         temp.seconds -= 60;
         temp.minutes++;
     }
     temp.minutes += rhs.minutes;
     if (temp.minutes >= 60) {
         temp.minutes -= 60;
         temp.hours++;
     }
     temp.hours += rhs.hours;
     return temp;
 }
</syntaxhighlight>

<code>this</code>에서 작동되는 클래스 메서드로 정의된 [[단항 연산자]]는 명백한 인수를 받을 일은 없을 거라고 한다:

<syntaxhighlight lang="cpp">
 bool Time::operator!() const {
     return ((hours == 0) && (minutes == 0) && (seconds == 0));
 }
</syntaxhighlight>

== 비평 ==
연산자 오버로딩은 프로그래머가 연산자에 완전히 다른 의미를 줄 수 있기 때문에 비판을 받아왔다. 예를 들어, [[C++]]에서 연산자 <code>&lt;&lt;</code> 사용시 :
<syntaxhighlight lang="cpp">
a << 1
</syntaxhighlight>
<code>a</code>는 정수 형식의 경우 1 비트로 남아있는 변수 <code>a</code>의 비트를 쉬프트한다, 하지만 만약 <code>a가</code> 출력 스트림일 경우 그러면 위의 코드는 출력 스트림에 "1" 을 출력한다.

이 비판에 대한 일반적인 답변은 동일한 인자뿐 아니라 오버로딩을 함수에 적용되는 것이다. 또한 심지어는 오버로딩이 없는 상태에서 프로그래머는 이름에서 예상되는 것과 완전히 다른 일을 하는 함수를 정의할 수 있다. 남아있는 문제는 그 언어와 같은 C++ 연산자 기호의 제한된 집합을 제공하고 따라서 프로그래머의 새로운 작업에 대한 보다 적절한 연산자 기호를 선택 옵션에서 제거한다.

또, 연산자와 함께 더 많은 미묘한 문제는 수학에서 특정 규칙이 잘못 예상 또는 실수로 간주 될 수 있다는 것이다. 예를 들면 +의 교환 법칙 (예: <code> a + b == b + a </code>) 이 항상 적용되지 않는다; 피연산자가 문자열일 때 이 예제가 발생한다, +는 일반적으로 오버로딩이 있기 때문에 문자열 연결을 수행한다. (예: <code>"school" + "bag"</code>은 <code>"schoolbag"</code>을 산출, 이것은 <code>"bag" + "school"</code>은 <code>"bagschool"</code>을 산출하는 것과 다르다). 일반 계산 인수로 수학에서 직접 제공한다: + 는 정수에서 교환법칙이 성립 (그리고 일반적으로 어떠한 실제 숫자) 하는 동안, 그것은 변수의 다른 "종류"에 대한 교환법칙이 성립하지 않는다. 반올림 오류로 인해 실제 [[부동소수점]] 값에서 그것은 그 + 도 연관되지 않다고 더 지적할 수 있다. 또 다른 예를 들어: [[이항연산]] * (곱셈) 은 정수에 대한 교환법칙이 성립하지만, [[행렬 곱셈]]의 경우 교환법칙이 성립하지 않는다.

== 목록 ==
몇 가지 일반적인 프로그래밍 언어의 분류는 프로그래머와 연산자가 미리 정의된 집합으로 오버로드 가능 여부를 나타낸 것이다.
{| class="wikitable"
|-
! 연산자
! 오버로딩 불가능
! 오버로딩 가능
|-
! 신규 정의
| <!-- "오버로딩 불가능"과 "새 연산자 정의" -->
* [[ML (프로그래밍 언어)|ML]]
* [[Pico 프로그래밍 언어|Pico]]<ref>상징적인 이름으로 바이너리 기능 삽입을 호출할 수 있다</ref>
* [[프롤로그 (프로그래밍 언어)|프롤로그]]
| <!-- "오버로딩 가능"과 "신규 정의" -->
* [[ALGOL 68#op: 연산자|ALGOL 68]]
* [[Eiffel (프로그래밍 언어)|Eiffel]]
* [[포트란]]<ref>포트란 90에서 소개</ref>
* [[F 샤프|F#]]
* [[하스켈]]<ref>오버로딩의 유형 클래스를 대신함</ref>
* [[아이오 (프로그래밍 언어)|아이오]]
* [[라쿠 (프로그래밍 언어)|펄 6]]
* [[R (프로그래밍 언어)|R]]
* [[스칼라 (프로그래밍 언어)|스칼라]]
* [[스몰토크]]
|-
! 제한된 집합
| <!-- "오버로딩 불가능"과 "연산자의 제한된 설정" -->
* [[C (프로그래밍 언어)|C]]
* [[자바 (프로그래밍 언어)|자바]]
* [[자바스크립트]]
* [[모듈라-2]]
* [[오브젝티브-C]]
* [[파스칼 (프로그래밍 언어)|파스칼]]
* [[베이직]]
|<!-- "오버로딩 가능"과 "연산자의 제한된 설정" -->
* [[에이다 (프로그래밍 언어)|에이다]]
* [[C++]]
* [[C 샤프|C#]]
* [[D (프로그래밍 언어)|D]]
* [[프리베이직]]
* [[그루비 (프로그래밍 언어)|그루비]]
* [[루아 (프로그래밍 언어)|루아]]
* [[델파이]] (2005년)
* [[오브젝트 파스칼]] ([[프리 파스칼]]<ref>{{웹 인용 | title=Operator Overloading, Free Pascal Manual | url=http://www.freepascal.org/docs-html/ref/refse66.html#x162-17200012.1 | accessdate=June 2011 | archive-date=2011-06-23 | archive-url=https://web.archive.org/web/20110623013033/http://freepascal.org/docs-html/ref/refse66.html#x162-17200012.1 | url-status=dead }}</ref>)
* [[PHP]] (magic 메서드이나 ArrayAccess 인터페이스나 운영자 확장을 사용)
* [[펄]]
* [[파이썬]]
* [[루비 (프로그래밍 언어)|루비]]
* [[비주얼 베이직 닷넷|비주얼 베이직 2005]]
* 코틀린
|}

== 연산자 오버로딩의 연대순 ==
=== 1960년대 ===
[[ALGOL 68]] 기능은 연산자 오버로딩을 허용한다.<ref>{{웹 인용 | title=알고리즘 언어 ALGOL 68에 대한 보고서, Section 10.2.2. | url=http://www.fh-jena.de/~kleine/history/languages/Algol68-Report.pdf | format=PDF | author=[[Adriaan van Wijngaarden|A. van Wijngaarden]], [[Barry J. Mailloux|B.J. Mailloux]], [[John E. L. Peck|J.E.L. Peck]] and [[Cornelis H.A. Koster|C.H.A. Koster]], et al. | accessdate=April 2007 | year=1968 | month=August | archive-date=2012-07-17 | archive-url=https://web.archive.org/web/20120717020610/http://www.fh-jena.de/~kleine/history/languages/Algol68-Report.pdf | url-status=dead }}</ref>

연산자 오버로딩 ¬, =, ≠ 그리고 '''abs'''가 정의된 '''ALGOL 68''' 언어 기능 (페이지 177)에서 추출:
 10.2.2. 부울 피연산자에 대한 연산
 a) '''op''' ∨ = ('''bool''' a, b) '''bool''':( a | '''true''' | b );
 b) '''op''' ∧ = ('''bool''' a, b) '''bool''': ( a | b | '''false''' );
 c) '''op''' ¬ = ('''bool''' a) '''bool''': ( a | '''false''' | '''true''' );
 d) '''op''' = = ('''bool''' a, b) '''bool''':( a∧b ) ∨ ( ¬b∧¬a );
 e) '''op''' ≠ = ('''bool''' a, b) '''bool''': ¬(a=b);
 f) '''op''' '''abs''' = ('''bool''' a)'''int''': ( a | 1 | 0 );
특별한 선언이 연산자를 오버로드하기 위해 필요하지 않는다는 점을 참고하고, 프로그래머는 새로운 연산자를 자유롭게 만들 수 있다.

=== 1980년대 ===
[[에이다 (프로그래밍 언어)|에이다]]는 에이다 83 언어 표준의 출판과 함께 처음 소개됨에서 연산자 오버로딩을 지원한다. 그러나, 언어의 설계자는 새로운 연산자의 정의를 허용하지 않도록 선택한다: 단지 언어의 기존 연산자 (예 : "+", "*", "and" 등 식별자 새로운 기능을 정의하여)를 오버로딩할 수 있다. 언어의 후속 개정 (1995년과 2005년)은 기존 연산자의 오버로딩에 대한 제한을 유지한다.

[[C++]]의 연산자 오버로딩은 [[ALGOL 68]]에서 더 수정되었다.<ref>{{웹 인용|title=C++의 역사: 1979−1991 - 페이지 12 | url=http://www.research.att.com/~bs/hopl2.pdf |format=PDF| author=Bjarne Stroustrup | accessdate= April 2007 }}</ref>

=== 1990년대 ===
Sun은 자바 언어로 오버로딩 연산자를 포함하지 않기로 선택한다.<ref>[http://www.cafeaulait.org/javafaq.html#xtocid1902938]</ref><ref>[http://java.sun.com/docs/white/langenv/Simple.doc2.html]</ref>

=== 2001년 ===
마이크로소프트는 [[C 샤프|C#]]에서 연산자의 오버로딩을 포함했다.

== 같이 보기 ==
* [[함수 오버로드]]
* [[다형성]]
* [[함수 (프로그래밍)]]
* [[연산자 (프로그래밍)]]
* [[C와 C++에서의 연산자]]

== 각주 ==
{{각주}}

{{프로그래밍 구성체}}
{{C++}}
{{전거 통제}}

[[분류:ALGOL 68 코드 예시에 관한 문서]]
[[분류:연산자 (프로그래밍)]]
[[분류:프로그래밍 구성체]]