함수 오버로딩 (Function Overloading)¶
호출 사이트를 보는 독자가 먼저 어떤 오버로드가 호출되고 있는지 정확히 파악하지 않고도 무슨 일이 일어나고 있는지 잘 알 수 있는 경우에만 오버로드된 함수(생성자 포함)를 사용하세요.
const std::string& 을 취하는 함수를 작성하고 const char* 를 취하는 다른 함수로 오버로드할 수 있습니다. 그러나 이 경우 std::string_view를 대신 고려하십시오.
class MyClass {
public:
void Analyze(const std::string& text);
void Analyze(const char* text, size_t textlen);
};
오버로딩은 동일한 이름의 함수가 다른 인수를 취할 수 있도록 하여 코드를 더욱 직관적으로 만들 수 있습니다. 템플릿화된 코드에 필요할 수 있으며 방문자에게 편리할 수 있습니다.
const 또는 ref 한정을 기반으로 한 오버로드는 유틸리티 코드를 더 유용하게 만들고, 더 효율적으로 만들거나 두 가지 모두를 가능하게 할 수 있습니다. 자세한 내용은 TotW #148을 참조하세요.
함수가 인수 유형만으로 오버로드되는 경우 독자는 무슨 일이 일어나고 있는지 알아보기 위해 C++의 복잡한 일치 규칙을 이해해야 할 수도 있습니다. 또한 파생 클래스가 함수 변형 중 일부만 재정의하는 경우 많은 사람들이 상속의 의미를 혼동합니다.
변형 간에 의미상 차이가 없는 경우 함수를 오버로드할 수 있습니다. 이러한 오버로드는 유형, 한정자 또는 인수 수가 다를 수 있습니다. 그러나 이러한 호출을 읽는 사람은 오버로드 세트의 어떤 멤버가 선택되었는지 알 필요가 없으며 세트의 항목이 호출되고 있다는 것만 알 수 있습니다.
이 통합 디자인을 반영하려면 전체 오버로드 세트를 문서화하고 첫 번째 선언 앞에 배치되는 포괄적인 단일 "우산" 주석을 선호합니다.
독자가 포괄적 주석을 특정 오버로드에 연결하는 데 어려움을 겪을 수 있는 경우 특정 오버로드에 대한 주석을 갖는 것은 괜찮습니다.
이해하기 쉽게 설명하기¶
핵심: 호출 지점에서 "무슨 일이 일어나는지" 분명할 때만 오버로드¶
오버로드된 함수는, 호출하는 쪽 독자가 어떤 오버로드가 선택되는지 따지지 않고도 무슨 일이 일어나는지 알 수 있을 때만 쓰세요.
class MyClass {
public:
void Analyze(const std::string& text);
void Analyze(const char* text, size_t textlen);
};
위처럼 const std::string&과 const char*로 오버로드할 수 있지만, 이런 경우엔 std::string_view 하나로 받는 편이 더 낫습니다.
좋은 오버로드 / 나쁜 오버로드¶
- 좋음: 변형 간 의미 차이가 없어, 어느 게 불려도 결과가 같은 경우.
const/참조 한정에 따른 오버로드도 유용합니다. - 나쁨: 인수 타입만으로 갈리고, 독자가 C++의 복잡한 오버로드 해소 규칙을 알아야 동작을 이해할 수 있는 경우. 파생 클래스가 일부 변형만 재정의하면 상속 의미가 헷갈립니다.
문서화¶
하나의 통합된 오버로드 집합은, 첫 선언 앞에 전체를 설명하는 하나의 "우산" 주석을 선호합니다. 독자가 특정 오버로드와 연결하기 어려울 때만 개별 주석을 답니다.