연산자 오버로드

Operator overloading

컴퓨터 프로그래밍에서 연산자 오버로드(operator overloading)는 때때로 연산자 애드혹 다형(operator ad hoc polymorphism)이라고 불리며, 다른 연산자들이 그들의 인수에 따라 다른 구현을 갖는 다형성의 특정한 경우이다.연산자 오버로드는 일반적으로 프로그래밍 언어, 프로그래머 또는 둘 다에 의해 정의됩니다.

근거

연산자 오버로드는 구문 설탕으로, 대상 도메인에[1] 가까운 표기법을 사용하여 프로그래밍할 수 있고 사용자 정의 유형이 언어에 내장된 유형과 유사한 수준의 구문 지원을 허용하기 때문에 사용됩니다.예를 들어 과학적 컴퓨팅에서는 수학적인 오브젝트의 컴퓨팅 표현을 종이와 같은 구문으로 조작할 수 있는 것이 일반적입니다.

연산자 오버로드는 함수 호출을 사용하여 에뮬레이트할 수 있기 때문에 언어의 표현력(함수 포함)을 변경하지 않습니다.예를 들어 변수를 고려합니다.a,b그리고.c일부 사용자 정의 유형(예: 매트릭스:

a + b * c

연산자 오버로드를 지원하는 언어에서는 '*' 연산자가 '+' 연산자보다 우선 순위가 높다는 일반적인 가정 하에 다음과 같이 간결하게 기술합니다.

Add(a, Multiply(b, c))

단, 전자의 구문은 일반적인 수학적 용법을 반영하고 있습니다.

이 경우 사용자 정의 유형에 추가할 수 있도록 추가 연산자가 오버로드됩니다.TimeC++:

시간을 교환입니다.+(컨스턴트 시간을& lhs, 컨스턴트 시간을& rhs) {   시간을 임시직 = lhs;   임시직.초수 += rhs.초수;   임시직.회의록 += 임시직.초수 / 60;   임시직.초수 %= 60;   임시직.회의록 += rhs.회의록;   임시직.몇시간. += 임시직.회의록 / 60;   임시직.회의록 %= 60;   임시직.몇시간. += rhs.몇시간.;   돌아가다 임시직; } 

덧셈은 2진수 연산입니다.즉, 2개의 오퍼랜드가 있습니다.C++에서는 전달되는 인수는 오퍼랜드와tempobject는 반환된 값입니다.

이 작업은 클래스 메서드로 정의할 수도 있습니다.lhs숨어서this단, 이 경우 왼쪽 오퍼랜드가 강제로 타입이 됩니다.Time:

// 시작 중괄호 바로 앞에 "const"가 있으면 수정되지 않습니다. 시간을 시간을::교환입니다.+(컨스턴트 시간을& rhs) 컨스턴트 {   시간을 임시직 = *이것.;  // 이것은 수정하면 안 되므로 복사하십시오.   임시직.초수 += rhs.초수;   임시직.회의록 += 임시직.초수 / 60;   임시직.초수 %= 60;   임시직.회의록 += rhs.회의록;   임시직.몇시간. += 임시직.회의록 / 60;   임시직.회의록 %= 60;   임시직.몇시간. += rhs.몇시간.;   돌아가다 임시직; } 

클래스 메서드로 정의된 단항 연산자는 명백한 인수를 수신하지 않습니다(이 연산자는 에서만 동작합니다).this):

부울 시간을::교환입니다.!() 컨스턴트 {   돌아가다 몇시간. == 0 & & 회의록 == 0 & & 초수 == 0; } 

구조체 또는 클래스를 정렬하기 위해 less than (<) 연산자가 오버로드되는 경우가 많습니다.

학급  {  일반의:   부울 교환입니다.< >(컨스턴트 & p) 컨스턴트 {     한다면 (x_ == p.x_) {       돌아가다 y_ < > p.y_;     }     돌아가다 x_ < > p.x_;   }   사적인:   인트 x_;   인트 y_; }; 

위의 예와 마찬가지로 마지막 예에서는 연산자 오버로드가 클래스 내에서 수행됩니다.C++에서는 less than 연산자(<)를 오버로드한 후 표준 정렬 함수를 사용하여 일부 클래스를 정렬할 수 있습니다.

비판

연산자 오버로드는 프로그래머가 연산자의 시멘틱스를 그들의 피연산자의 유형에 따라 재할당 할 수 있게 해주기 때문에 종종 비판을[2] 받아왔다.예를 들어, 의 사용법<<C++ 연산자 a << b변수의 비트를 이동하다a남겨진b을 비트로 하다a그리고.b정수형이지만a출력 스트림입니다.상기 코드는 다음 명령어의 기입을 시도합니다.b개울로.연산자 오버로드는 원래 프로그래머가 연산자의 일반적인 의미를 변경하고 후속 프로그래머를 기습적으로 잡을 수 있도록 하기 때문에 연산자 오버로드를 주의 깊게 사용하는 것이 좋은 관행으로 간주됩니다(이러한 이유 때문만은 아니지만 [3]자바 개발자들은 이 기능을 사용하지 않기로 결정했습니다).

연산자의 또 다른 미묘한 문제는 수학의 특정 규칙이 잘못 예상되거나 의도하지 않게 가정될 수 있다는 것이다.예를 들어 +의 교환율(즉,a + b == b + a는 반드시 적용되는 것은 아닙니다.오퍼랜드가 스트링일 경우, 그 예가 됩니다.+는 일반적으로 스트링의 연동을 실행하기 위해 오버로드되기 때문입니다(즉,"bird" + "song"수율"birdsong",하는 동안에"song" + "bird"수율"songbird"이 주장에 대한 전형적인[citation needed] 반론은 수학에서 직접 나옵니다.+는 정수(및 일반적으로 모든 복소수)에 대해 가환이지만 변수의 다른 "유형"에는 가환하지 않습니다.실제로는 반올림 오류로 인해 +가 부동소수점 값과 항상 연관되는 것은 아닙니다.또 다른 예는 다음과 같습니다.수학에서 곱셈은 실수와 복소수에는 가환이지만 행렬 곱셈에서는 가환적이지 않다.

카탈로그

몇 가지 공통 프로그래밍 언어의 분류는 그 연산자가 프로그래머에 의해 오버로드 가능한지 여부 및 연산자가 미리 정의된 집합으로 제한되는지 여부에 따라 이루어진다.

연산자 과부하 불가 과부하
새로운[4] 정의 가능
한정 세트

연산자 오버로드의 타임라인

1960년대

ALGOL 68 사양에서는 연산자의 오버로드가 [44]허용되었습니다.

과부하 연산자 spec, =, , abs가 정의되어 있는 ALGOL 68 언어 사양(17페이지)에서 발췌합니다.

10.2.2. 부울 연산자 a) op = (부울 a, b) bool:(진정한 b); b) op = (부울 a, b) bool: (a false ); c) op = (부울 a) bool: (a false true ); d) op == (부울 a: (bol a, bool a)

연산자를 오버로드하기 위해 특별한 선언이 필요하지 않으며 프로그래머는 새로운 연산자를 자유롭게 생성할 수 있습니다.

1980년대

Ada는 Ada 83 언어 표준의 출판과 함께 처음부터 연산자의 과부하를 지원한다.그러나 언어 설계자는 새로운 연산자의 정의를 배제하는 것을 선택했다."+", "*", "&" 등의 식별자를 사용하여 새로운 함수를 정의함으로써 해당 언어의 기존 연산자만 오버로드될 수 있습니다.언어의 후속 개정(1995년과 2005년)에서도 기존 연산자의 과부하 제한이 유지된다.

C++에서는 연산자 오버로드가 ALGOL [45]68보다 정교해진다.

1990년대

Sun Microsystems의 Java 언어 디자이너는 과부하를 [46][47][48]생략하기로 했습니다.

루비는 오퍼레이터가 간단한 메서드 호출을 위해 구문 설탕으로 오버로드할 수 있도록 합니다.

Lua는 첫 번째 피연산자가 해당 연산자를 정의하지 않으면 두 번째 피연산자에 대한 메서드가 사용되는 기능이 추가된 메서드 호출에 대한 구문 설탕으로 연산자 오버로드를 허용합니다.

2000년대

Microsoft는 2001년에 연산자 오버로드를 C# 및 Visual Basic에 추가했습니다.2003년의 NET.

Scala는 모든 연산자를 메서드로 취급하므로 프록시에 의한 연산자 오버로드를 허용합니다.

Raku에서는 모든 연산자의 정의를 어휘 함수에 위임하기 때문에 함수 정의를 사용하여 연산자를 오버로드하거나 새로운 연산자를 추가할 수 있다.예를 들어, Rakudo 소스에 정의되어 있는 Date 객체를 "+"로 증가시키는 함수는 다음과 같습니다.

multi infix:<+>(날짜:D $d, Int:D $x) {Date.new-from-daycount($d.daycount + $x)}

"multi"가 사용되었기 때문에 함수는 멀티디스패치 후보 목록에 추가되고 "+"는 함수 시그니처의 유형 제약 조건이 충족되는 경우에만 오버로드됩니다.오버로드 용량에는 +, *, >=, postfixterm i 등이 포함되지만 "x, y], "x[ y ]", "x{ y }" 및 "x( y )"와 같은 다양한 가새 연산자가 오버로드될 수도 있습니다.

Kotlin은 생성 이후 연산자 오버로드를 지원했습니다.

「 」를 참조해 주세요.

레퍼런스

  1. ^ Stroustrup, Bjarne. "Operator Overloading". C++ FAQ. Archived from the original on 14 August 2011. Retrieved 27 August 2020.
  2. ^ Fisher, Charles N. (2008). "Issues in Overloading" (PDF). University of Wisconsin–Madison.
  3. ^ "No more operator overloading". The Java Language Environment. Oracle Corporation.
  4. ^ 완전히 새로운 연산자를 추가할 수 있습니다.
  5. ^ 기호 이름을 가진 이진 함수는 infix라고 할 수 있습니다.
  6. ^ "Predicate op/3".
  7. ^ Hunt, John (6 December 2012). Smalltalk and Object Orientation: An Introduction. Springer Science & Business Media. ISBN 978-1-4471-0961-7.
  8. ^ "Bertrand Meyer: Basic Eiffel language mechanisms". se.ethz.ch. Retrieved 7 April 2021.
  9. ^ "Operator functions in F90". www.mathcs.emory.edu. Retrieved 7 April 2021.{{cite web}}: CS1 maint :url-status (링크)
  10. ^ Fortran 90에서 도입되었습니다.
  11. ^ "3. Language Reference — Futhark 0.19.0 documentation". futhark.readthedocs.io. Retrieved 10 October 2020.
  12. ^ Smith, Chris (9 October 2012). Programming F# 3.0: A Comprehensive Guide for Writing Simple Code to Solve Complex Problems. O'Reilly Media, Inc. ISBN 978-1-4493-2604-3.
  13. ^ 오버로드 대신 클래스를 입력합니다.
  14. ^ "io guide". iolanguage.org. Retrieved 7 April 2021.
  15. ^ "Operators".
  16. ^ "Operators - R in a Nutshell, 2nd Edition [Book]". www.oreilly.com. Retrieved 7 April 2021.
  17. ^ "Creating operators".
  18. ^ "Operators". Tour of Scala.
  19. ^ "Seed7 Manual: Structured syntax definition". seed7.sourceforge.net. Retrieved 29 September 2020.
  20. ^ "Swift: Advanced Operators".
  21. ^ "Why does Go not support overloading of methods and operators?". Retrieved 4 September 2011.
  22. ^ "Introduction". freepascal.org. Retrieved 30 September 2020.
  23. ^ "Operator Overloads". Retrieved 28 September 2018.
  24. ^ "6.6 Overloading of Operators". Annotated Ada Reference Manual.
  25. ^ Drayton, Peter; Albahari, Ben; Neward, Ted (2003). C# in a Nutshell. O'Reilly Media, Inc. ISBN 978-0-596-00526-9.
  26. ^ "C++ Operator Overloading".
  27. ^ "Eclipse Ceylon: Operator Polymorphism". ceylon-lang.org. Retrieved 7 April 2021.
  28. ^ "Operator Overloading - D Programming Language". dlang.org. Retrieved 10 October 2020.
  29. ^ "A tour of the Dart language". dart.dev. Retrieved 30 September 2020.
  30. ^ "Operator Overloading". bourabai.kz. Retrieved 7 April 2021.
  31. ^ "The Apache Groovy programming language - Operators". groovy-lang.org. Retrieved 30 September 2020.
  32. ^ "Operator Overloading". Manifold. Retrieved 7 June 2020.
  33. ^ "Operator overloading". Kotlin. Retrieved 24 June 2018.
  34. ^ "Metamethods Tutorial". Lua-users Wiki.
  35. ^ "Implementing Operators for Your Class". Retrieved 1 October 2013.
  36. ^ "Operator Overloading". Free Pascal Manual. Retrieved 1 December 2014.
  37. ^ "Operator Overloading". Delphi Manual. Retrieved 1 December 2014.
  38. ^ "PHP magic methods overriding class properties". Archived from the original on 4 March 2016. Retrieved 7 April 2015.
  39. ^ Orwant, Jon (4 November 2002). Computer Science & Perl Programming: Best of The Perl Journal. O'Reilly Media, Inc. pp. 347–. ISBN 978-0-596-00310-4.
  40. ^ "3. Data Model". The Python Language Reference.
  41. ^ "Methods". Official Ruby FAQ.
  42. ^ "Operator Overloading". Rust By Example.
  43. ^ "How to: Define an Operator (Visual Basic)".
  44. ^ Wijngaarden, Adriaan; Mailloux, Barry J.; Peck, John E. L.; Koster, Cornelis H. A.; et al. (August 1968). "Report on the Algorithmic Language ALGOL 68, Section 10.2.2" (PDF). Retrieved 1 April 2007.
  45. ^ Stroustrup, Bjarne. "A History of C++: 1979−1991" (PDF). p. 12. Retrieved 1 April 2007.
  46. ^ "FAQ Question 6.9: Why isn't there operator overloading?". The comp.lang.java FAQ List.
  47. ^ "java.sun.com". Archived from the original on 7 March 2009. Retrieved 26 March 2009.
  48. ^ Holzner, Steven (2001). C++: Black Book. Scottsdale, Arizona: Coriolis Group. p. 387. ISBN 1-57610-777-9. One of the nicest features of C++ OOP is that you can overload operators to handle objects of your classes (you can't do this in some other OOP-centric languages, like Java).