동일한 이름의 함수가 있지만 기본 및 파생 클래스에 다른 서명이 있습니다. 파생에서 상속 된 다른 클래스에서 기본 클래스의 함수를 사용하려고하면 오류가 발생합니다. 다음 코드를 참조하십시오.
class A
{
public:
void foo(string s){};
};
class B : public A
{
public:
int foo(int i){};
};
class C : public B
{
public:
void bar()
{
string s;
foo(s);
}
};
gcc 컴파일러에서 다음 오류를 수신합니다.
In member function `void C::bar()': no matching function for call to `C::foo(std::string&)' candidates are: int B::foo(int)
int foo(int i){};
class B
에서 제거 하거나에서 이름을 바꾸면 foo1
모든 것이 잘 작동합니다.
이것의 문제는 무엇입니까?
답변
기본 클래스의 함수를 재정의하지 않지만 이름이 같은 파생 클래스의 함수는 기본 클래스에서 같은 이름의 다른 함수를 숨 깁니다 .
일반적으로보고있는 것이 일반적으로 바람직한 동작이 아니므로 기본 클래스 함수를 재정의하지 않는베이스 클래스의 함수와 이름이 같은 파생 클래스에 함수를 포함하는 것은 나쁜 습관으로 간주됩니다. 일반적으로 다른 기능에 다른 이름을 지정하는 것이 좋습니다.
기본 함수를 호출해야하는 경우를 사용하여 호출 범위를 지정해야합니다 A::foo(s)
. 이렇게하면 동시에 가상 기능 메커니즘도 비활성화 A::foo(string)
됩니다.
답변
기지 중 하나에서 이름을 찾으면 이름 조회가 중지되기 때문입니다. 그것은 다른 기지를 넘어 보지 않을 것입니다. B의 함수 그림자 두 함수 B 및 C 내에서 표시되도록하는 것이, B의 범위에서의 기능을 재 – 선언 당신이 가지고 A. 펑션 :
class A
{
public:
void foo(string s){};
};
class B : public A
{
public:
int foo(int i){};
using A::foo;
};
class C : public B
{
public:
void bar()
{
string s;
foo(s);
}
};
편집 : 표준이 제공하는 실제 설명은 (10.2 / 2에서) :
다음 단계에서는 클래스 범위 C에서 이름 조회의 결과를 정의합니다. 먼저 클래스와 각 기본 클래스 하위 개체의 이름에 대한 모든 선언이 고려됩니다. 한 하위 개체 B의 멤버 이름 f는 A가 B의 기본 클래스 하위 개체 인 경우 하위 개체 A에서 멤버 이름 f를 숨 깁니다. 이렇게 숨겨진 선언은 고려 대상에서 제거됩니다. using-declaration에 의해 도입 된 이러한 각 선언은 using-declaration에 의해 지정된 선언을 포함하는 유형 인 C의 각 하위 개체에서 온 것으로 간주됩니다 .96) 결과 선언 집합이 그렇지 않은 경우 모두 동일한 유형의 하위 개체에서 가져 오거나 세트에 비 정적 멤버가 있고 별개의 하위 개체의 멤버를 포함하는 경우 모호성이 있고 프로그램의 형식이 잘못되었습니다. 그렇지 않으면 그 세트는 조회의 결과입니다.
다른 위치 (바로 위)에서 다음과 같이 말할 수 있습니다.
id-expression [ “foo”와 같은 ]의 경우 이름 조회는 this의 클래스 범위에서 시작됩니다. 정규화 된 ID의 경우 [ “A :: foo”와 같은 A는 중첩 된 이름 지정자입니다. ], 이름 검색은 중첩 된 이름 지정자의 범위에서 시작됩니다. 이름 조회는 액세스 제어 전에 발생합니다 (3.4, 11 절).
([…] 내가 쓴). B의 foo가 비공개 인 경우에도 A의 foo를 찾을 수 없습니다 (액세스 제어가 나중에 발생하기 때문에).