함수 오버로드

Function overloading

일부 프로그래밍 언어에서 함수 오버로드 또는 메서드 오버로드는 다른 구현으로 동일한 이름의 함수를 여러 개 생성하는 기능입니다.과부하된 함수에 대한 호출은 콜의 컨텍스트에 적합한 특정 함수의 구현을 실행하므로 1개의 함수 호출이 컨텍스트에 따라 다른 작업을 수행할 수 있습니다.

예를들면,doTask()그리고.doTask(object o)과부하 함수입니다.후자를 호출하려면 오브젝트파라미터로 전달되어야 하는데, 전자는 파라미터가 필요하지 않고 빈 파라미터 필드로 호출됩니다.일반적인 오류는 두 번째 함수의 개체에 기본값을 할당하는 것입니다. 그러면 컴파일러는 두 가지 방법 중 어떤 방법을 사용해야 하는지 알 수 없기 때문에 모호한 호출 오류가 발생합니다.

또 다른 예는Print(object o)텍스트인지 사진인지 여부에 따라 다른 동작을 실행하는 기능입니다.2개의 다른 함수는 다음과 같이 과부하될 수 있습니다.Print(text_object T); Print(image_object P)프로그램이 "인쇄"하는 모든 객체에 대해 오버로드된 인쇄 함수를 작성하면 객체의 종류에 대해 걱정할 필요가 없으며 올바른 함수 호출을 다시 수행할 경우 호출은 항상 다음과 같습니다. Print(something).

오버로드에 대응하는 언어

함수 오버로드를 지원하는 언어는 다음과 같습니다(이것들에 한정되는 것은 아닙니다.

함수 오버로드에 있는 규칙

  • 두 개 이상의 함수 정의에 동일한 함수 이름이 사용됩니다.
  • 함수는 매개 변수의 특성 또는 유형에 따라 달라야 합니다.

이것은 정적 다형성의 분류로 함수 호출이 "최적 일치" 알고리즘을 사용하여 해결됩니다.여기서 호출하는 특정 함수는 형식 파라미터 유형과 실제 파라미터 유형이 가장 일치하는 것을 발견함으로써 해결됩니다.이 알고리즘의 자세한 내용은 언어에 따라 다릅니다.

함수 오버로드는 보통 함수 호출에서 유형 체크를 강제하는 정적 유형의 프로그래밍 언어와 관련지어집니다.과부하 함수는 실제로 같은 이름을 가진 여러 함수의 집합일 뿐입니다.특정 콜에 사용할 함수의 결정은 컴파일 시에 해결됩니다.

Java에서 함수 오버로드는 컴파일 시간 다형 및 정적 다형이라고도 합니다.

함수 오버로드는 정적 대신 가상 기능을 통해 런타임에 선택되는 다형성과 혼동해서는 안 됩니다.

예:C++에서의 함수 오버로드

#실패하다 <iostream>  인트 용량(인트 s) {  // 큐브의 볼륨입니다.   돌아가다 s * s * s; }  이중으로 하다 용량(이중으로 하다 r, 인트 h) {  // 실린더의 볼륨.   돌아가다 3.1415926 * r * r * static_cast< >이중으로 하다>(h); }   용량( l, 인트 b, 인트 h) {  // 입방체의 부피.   돌아가다 l * b * h; }  인트 주된() {   표준::외치다 << > 용량(10);   표준::외치다 << > 용량(2.5, 8);   표준::외치다 << > 용량(100리터, 75, 15); } 

위의 예에서 각 성분의 부피는 "부피"라는 이름의 세 가지 함수 중 하나를 사용하여 계산되며 실제 파라미터의 수와 유형에 따라 선택됩니다.

컨스트럭터 오버로드

오브젝트 인스턴스를 작성하기 위해 사용되는 컨스트럭터는 일부 오브젝트 지향 프로그래밍 언어에서도 오버로드될 수 있습니다.많은 언어에서 생성자의 이름은 클래스의 이름으로 미리 결정되기 때문에 생성자는 한 명뿐인 것으로 보입니다.여러 개의 컨스트럭터가 필요할 때마다 과부하 함수로 구현해야 합니다.C++에서는 디폴트컨스트럭터는 파라미터를 사용하지 않고 오브젝트멤버를 적절한 디폴트값으로 인스턴스화합니다.이 값은 보통 숫자 필드에는 0, 문자열 [5]필드에는 빈 문자열입니다.예를 들어 C++로 작성된 레스토랑 청구 객체의 기본 생성자는 팁을 15%로 설정할 수 있습니다.

청구서()     : 팁.(0.15), // 퍼센티지       (0.0) { } 

단점은 생성된 Bill 객체의 값을 변경하는 데 두 가지 단계가 필요하다는 것입니다.다음은 메인 프로그램 내에서 값을 만들고 변경하는 방법을 보여 줍니다.

청구서 카페; 카페.팁. = 0.10; 카페. = 4.00; 

생성자를 오버로드하면 생성 시 팁과 합계를 매개 변수로 전달할 수 있습니다.여기에는 2개의 파라미터가 있는 오버로드된 컨스트럭터가 표시됩니다.이 오버로드된 생성자는 이전에 사용한 원래 생성자뿐만 아니라 클래스에 배치됩니다.어떤 것이 사용되는지는 새로운 Bill 오브젝트가 작성될 때 제공되는 파라미터의 수에 따라 달라집니다(없음 또는 2개).

청구서(이중으로 하다 팁., 이중으로 하다 )     : 팁.(팁.),       () { } 

이제 새로운 Bill 객체를 만드는 함수는 두 개의 값을 생성자로 전달하고 데이터 멤버를 한 번에 설정할 수 있습니다.다음은 작성 및 값 설정을 보여 줍니다.

청구서 카페(0.10, 4.00); 

이는 프로그램 효율을 높이고 코드 길이를 줄이는 데 유용합니다.

컨스트럭터 오버로드의 또 다른 이유는 필수 데이터 멤버를 강제 적용하는 것입니다.이 경우 디폴트 컨스트럭터는 외부에서 접근할 수 없도록 private 또는 protected(또는 C++11 이후 삭제)로 선언됩니다.위의 청구서의 경우, 총계(total)가 유일한 생성자 매개 변수일 수 있습니다. 청구서에는 총계(total)에 대한 합리적인 채무불이행(default)이 없기 때문입니다. 반면 팁은 0.15로 기본 설정됩니다.

합병증

이름 마스킹(스코프에 의한)과 암묵적 유형 변환이라는 두 가지 문제가 작용하여 함수 오버로드를 복잡하게 만듭니다.

함수가 1개의 스코프로 선언되어 같은 이름의 다른 함수가 내부 스코프로 선언된 경우, 2개의 자연스러운 오버로드 동작이 있습니다.내부 선언은 외부 선언을 마스크하거나(시그니처에 관계없이), 내부 선언과 외부 선언 모두 오버로드에 포함됩니다.er 선언은 시그니처가 일치하는 경우에만 외부 선언을 마스킹합니다.첫 번째는 C++로 취득됩니다.C++에서는 [6]스코프 전체에 오버로드가 발생하지 않습니다.그 결과, 다른 스코프에서 선언된 함수로 오버로드 세트를 얻으려면 외부 스코프에서 내부 스코프로 함수를 명시적으로 Import해야 합니다.using키워드를 지정합니다.

암묵적 유형 변환은 함수 오버로드를 복잡하게 합니다.이는 파라미터 유형이 오버로드된 함수 중 하나의 시그니처와 정확하게 일치하지 않지만 유형 변환 후에 일치할 수 있는 경우 해결 방법은 선택한 유형 변환에 따라 다르기 때문입니다.

이러한 조합은 혼란스러울 수 있습니다.예를 [6]들어 내부 스코프에서 선언된 부정확한 일치는 외부 스코프에서 선언된 정확한 일치를 마스킹할 수 있습니다.

예를 들어, 오버로드된 함수를 가진 파생 클래스는double또는int, 기능을 사용하여int기본 클래스의 C++에서는 다음과 같이 쓸 수 있습니다.

학급 B {  일반의:   무효 F(인트 i); };  학급 D : 일반의 B {  일반의:   사용. B::F;   무효 F(이중으로 하다 d); }; 

를 포함하지 않음using결과적으로int전달된 파라미터F파생 클래스에서 이중으로 변환되어 기본 클래스가 아닌 파생 클래스에서 함수와 일치한다. 다음을 포함한다.using파생 클래스에 과부하가 발생하여 기본 클래스의 함수와 일치합니다.

주의사항

과도한 오버로드로 설계된 메서드는 개발자가 단순히 코드를 읽는 것만으로 어떤 오버로드가 호출되는지 식별하기 어려울 수 있습니다.이는 오버로드된 파라미터 중 일부가 가능한 다른 파라미터의 상속된 유형(예: "object")인 경우에 특히 해당됩니다.IDE는 과부하 해결을 실행하여 올바른 과부하를 표시할 수 있습니다.

타입 베이스의 오버로드는, 코드 유지보수를 방해할 수도 있습니다.코드 업데이트로 인해 [7]컴파일러가 선택한 메서드의 오버로드가 잘못 변경될 수 있습니다.

「 」를 참조해 주세요.

레퍼런스

  1. ^ "Kotlin language specification". kotlinlang.org.
  2. ^ "37.6. Function Overloading". PostgreSQL Documentation. 2021-08-12. Retrieved 2021-08-29.
  3. ^ "Database PL/SQL User's Guide and Reference". docs.oracle.com. Retrieved 2021-08-29.
  4. ^ "Nim Manual". nim-lang.org.
  5. ^ Chan, Jamie (2017). Learn C# in One Day and Learn It Well (Revised ed.). p. 82. ISBN 978-1518800276.
  6. ^ a b Stroustrup, Bjarne. "Why doesn't overloading work for derived classes?".
  7. ^ Bracha, Gilad (3 September 2009). "Systemic Overload". Room 101.

외부 링크