2010-01-29 8 views
21

C++에서 프로토 타입 (매개 변수 개수, 유형 및 constness)이 다른 경우에도 기본 클래스의 멤버 함수는 의 파생 클래스 함수에 의해 재정의됩니까? 많은 웹 사이트에서 기능 프로토 타입이 동일해야한다고 말하기 때문에 이것은 바보 같은 질문입니다. 하지만 왜 아래 코드가 컴파일되지 않습니까? 상속의 아주 간단한 경우입니다.C++ 상속 및 함수 재정의

#include <iostream> 
using std::cout; 
using std::endl; 

class A {}; 
class B {}; 

class X 
{ 
public: 
    void spray(A&) 
    { 
     cout << "Class A" << endl; 
    } 
}; 

class Y : public X 
{ 
public: 
    void spray(B&) 
    { 
     cout << "Class B" << endl; 
    } 
}; 

int main() 
{ 
    A a; 
    B b; 
    Y y; 

    y.spray(a); 
    y.spray(b); 

    return 0; 
} 

GCC는 그래서 '숨어'라고

error: no matching function for call to `Y::spray(A&)' 
note: candidates are: void Y::spray(B&) 
+0

는 정교한 설명 같은 문제에 대해 말한다 C++ FAQ를 얻었다 :) http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq- 23.9 – legends2k

+1

서명이 동일해야한다고 말하는 것은 약간 위험합니다. 서명은 이름 맹 글링과 링크의 기초입니다. 서로 다른 클래스의 두 멤버는 다른 멤버를 재정의하더라도 항상 다른 서명을가집니다. "더 이상 동일한 매개 변수 유형, 이름 및 constness"라고 말하는 것이 좋습니다. 더 이상 말하지 않아도됩니다. –

+0

@litb : 명확히 해 주셔서 감사합니다! 나는 '프로토 타입'이 적당한 단어라고 생각한다. 나는 질문에서 그것을 바꿨다. :) – legends2k

답변

28

오히려 "무시"보다,이 "숨어"입니다 설명하는 데 사용되는 용어. 파생 클래스의 멤버는 기본적으로 동일한 서명이 있는지 여부에 관계없이 동일한 이름을 가진 기본 클래스의 멤버를 액세스 할 수 없게 만듭니다. 기본 클래스 멤버에 액세스하려는 경우 using 선언을 사용하여 파생 클래스로 가져올 수 있습니다. 이 경우, class Y에 다음을 추가합니다

using X::spray; 
+0

설명을 주셔서 감사합니다. 여기에 using 지시문을 추가하면 작동합니다. 하지만 스프레이 시그니처를 X에서 스프레이 (int)로 바꾸고 Y에서 스프레이 (float)로 y.spray (1)를 호출합니다. 및 y.spray (1.0f); 그것은 using 지시어없이 작동합니다. 어째서? – legends2k

+2

와우 죄송합니다, 내 잘못, 아직도 y의 스프레이 (float) 만 볼 때, y.spray (1); 이 타입은 int를 암시 적으로 float으로 변환합니다. – legends2k

+2

이것은 사람들이 더 잘 찾을 수 있도록 많은 검색 가루로 만들어진 특별한 질문을받을 가치가있는 답변 중 하나입니다. – Wug

10

를 던졌습니다 : Y::sprayX::spray을 숨 깁니다. 지시어를 사용하여 추가 :

class Y : public X 
{ 
public: 
    using X::spray; 
    // ... 
}; 
5

클래스 범위이며 수준의 범위는 부모에 중첩된다. 다른 중첩 된 범위 (네임 스페이스, 블록)와 똑같은 동작을합니다.

이름 조회가 이름 정의를 검색 할 때 현재 네임 스페이스를 찾은 다음 englobing 네임 스페이스를 찾은 다음 정의를 찾을 때까지 계속됩니다. 검색은 그 다음에 멈 춥니 다 (인수 종속 이름 조회에서 도입 된 복잡성을 고려하지 않고 인수 중 하나의 네임 스페이스에 정의 된 함수를 사용할 수있는 규칙 부분). 어떤 사람이 그것을 필요로하는 경우

+0

hinding의 근본적인 이유를 설명해 주셔서 감사합니다. 정말 왜 처음에 그 오류가 발생했는지, 그리고 왜 using 지시어가 그것을 해결했는지에 대해 말하고 있습니다. – legends2k