오버로드 된 가상 함수를 다시 선언해야하는 이유는 무엇입니까?
Nov 26 2020
두 개의 오버로드 된 함수 f(void)
와 f(int)
. 클래스 Derived
구현 f(int)
호출하여 f(void)
. Derived2
구현 f(void)
합니다.
컴파일러 Derived::f(int)
는 호출을 원하기 때문에 구현을 거부 f(int)
하지만 을 호출하고 싶어서 인수를 제공하지 않았습니다 f(void)
. 컴파일러가이를 거부하는 이유는 무엇입니까? 줄을 추가하면 virtual int f(void) = 0;
문제가 해결 되는 이유는 무엇 입니까?
class Base
{
public:
explicit Base(void) {}
virtual ~Base(void) {}
virtual int f(void) = 0;
virtual int f(int i) = 0;
};
class Derived : public Base
{
public:
// provide implementation for f(int) which uses f(void). Does not compile.
virtual int f(int i) {puts("Derived::f(int)"); return f();}
// code only compiles by adding the following line.
virtual int f(void) = 0;
};
class Derived2 : public Derived
{
public:
// overwrite only f(void). f(int) is implemented by Derived.
virtual int f(void) {puts("Derived2::f(void)"); return 4;}
};
int main(void)
{
Base * p = new Derived2();
int i0 = p->f(); // outputs Derived2::f(void) and returns 4
int i1 = p->f(1); // outputs "Derived::f(int) Derived2::f(void)" and return 4
delete p;
return 0;
}
답변
5 songyuanyao Nov 26 2020 at 08:18
Derived::f
Base::f
s를 숨 깁니다 . 주어 return f();
의 본문에 Derived::f(int)
이름이 f
범위에서 발견 Derived
한 후, 조회 이름 정지. 의 이름을 Base
찾을 수 없으며 과부하 해결에 참여합니다.
이름 조회는 모든 종류의 선언을 하나 이상 찾을 때까지 아래에 설명 된대로 범위를 검사합니다. 이때 조회가 중지되고 더 이상 범위는 검사되지 않습니다.
의 범위에 using Base::f;
이름을 소개하기 위해 추가 할 수 있습니다 .Base
Derived
class Derived : public Base
{
public:
using Base::f;
// provide implementation for f(int) which uses f(void).
virtual int f(int i) {puts("Derived::f(int)"); return f();}
};