파생 클래스에서 오버로딩이 안 되는 이유가 무엇인가요?
(많은 비슷한 질문들에서) 이 질문은 보통 몇몇 사람들이 잘못 예측하는 다음의 예제 때문에 나오게 되는데,
#include
using namespace std;
class B {
public:
int f(int i) { cout << "f(int): "; return i+1; }
// ...
};
class D : public B {
public:
double f(double d) { cout << "f(double): "; return d+1.3; }
// ...
};
int main()
{
D* pd = new D;
cout << pd->f(2) << '\n';
cout << pd->f(2.3) << '\n';
}
이 예제는 아래의 결과 대신
f(int): 3
f(double): 3.6
다음의 결과가 나옵니다.
f(double): 3.3
f(double): 3.6
정확히 말하자면, D와 B 사이에 Overload resolution(컴파일러에서 함수 호출을 컴파일할 때, 이름 or 템플릿 인수로 함수를 찾던 도중에 후보 함수가 둘 이상일 때 실제 호출될 함수를 선택하기 위한 작업)이 없습니다. 컴파일러는 D의 스코프를 검사하고, double f(double) 함수를 찾은 다음 호출을 하는데, 이때 B의 스코프는 신경쓰지 않습니다. C++은 스코프 사이에 오버로딩을 지원하지 않는데, 파생 클래스도 일반적인 규칙에서 예외는 아닙니다. (자세한 사항은 D&E 나 TC++PL3를 참고하시길 바랍니다).
그런데도 기본 클래스와 파생클래스의 f() 함수의 오버로드 셋을 만들고 싶으면 어떻게 해야 하나요?
그건 using 선언으로 쉽게 할 수 있습니다.
class D : public B {
public:
using B::f; // make every f from B available
double f(double d) { cout << "f(double): "; return d+1.3; }
// ...
};
이렇게 수정하면 출력은 다음과 같이 될 것인데
f(int): 3
f(double): 3.6
이는, B의 f()와 D의 f()에 overload resolution을 적용해 호출하기 가장 적절한 f()를 선택한 것입니다.
'번역 > Bjarne Stroustrup's C++ Style and Technique FAQ' 카테고리의 다른 글
Why can't I define constraints for my template parameters? (0) | 2020.03.04 |
---|---|
Can I use "new" just as in Java? (0) | 2019.12.09 |
Do we really need multiple inheritance? (0) | 2019.04.03 |
Why doesn't C++ have a universal class Object? (0) | 2019.03.07 |
Can I stop people deriving from my class? (2) | 2019.02.27 |
댓글