2011-08-26 2 views
6

내가 C++ 컴파일러는 이것을 받아 들일 수 없습니다 이유에 혼란 스러워요 : : : 내가 줄을 원하는왜 C++ 컴파일러는 상속 된 공개 메소드와 상속 된 private 메소드가 동일한 이름으로 불분명하지 않을까요?

request for member ‘Baz’ is ambiguous 
candidates are: void Bar::Baz() 
       void Foo::Baz() 

그러나 그것은 명확하지 않다 :

class Foo { 
    private: void Baz() { } 
    }; 

    class Bar { 
    public: void Baz() { 
    }; 

    class FooBar : public Foo, public Bar { }; 

    void main() { 
    FooBar fb; 
    fb.Baz(); 
    } 

오류 GCC주는 것은 Foo :: Baz()는 비공개이므로 Baz(). 왜 컴파일러가 여기에서 모호하지 않습니까?

답변

7

이름 확인은 두 단계로 진행됩니다. 먼저 이름이 조회 된 다음 액세스 이름이 검사됩니다. 이름 조회가 애매한 경우 액세스가 고려되지 않습니다.

이유는 어쩌면 의도적 인 언어 디자인 일 수도 있지만 이름을 확인하는 과정을 단순화하는 것이 더 쉽다고 생각합니다. 규칙은 이미 아주 복잡합니다.

+0

고의적입니다. 컴파일러를 더 간단하게 만드는 것은 아니지만 액세스가 추가 단계로 확인되어야하기 때문에 약간 더 복잡합니다. – curiousguy

3

명백하지 않습니다. 개인 회원에게 전화를 걸고 싶을 수도 있습니다 (가능한 경우).

공식적으로 언어 규칙은 이름이 먼저 해결되고 가장 좋은 과부하가 선택되었다고 말합니다. 그 다음에 만 접근성 검사가 있습니다.

1

액세스 제한은 상속에 영향을주지 않습니다. 모든 기본 클래스에서 모든 것을 상속받습니다.

class Base 
{ 
    virtual void secret_power() { /* innocent default */ } 
public: 
    void use_me() { secret_power(); } 
}; 

class Derived : public Base 
{ 
    virtual void secret_power() { /* overriding implementation here */ } 
}; 

이제 어떤 Base&을 위해 항상 비 가상 공용 인터페이스 use_me() 호출 할 수 있지만 파생 클래스는 제공 : 불필요한 보이지만, 약간 수정 된 버전을 고려할 수 있습니다 귀하의 경우에는 어디 민간 기능은 가상입니다 개인 가상의 구현.

2

이렇게하려면 개인 메서드를 호출 할 수있는 컨텍스트에 있는지 여부를 고려해야합니다. 이 후 전화를 허용 한 경우 :

fb.Baz() 

는 공용 또는 개인 컨텍스트에서 호출되었는지 여부에 따라 완전히 다른 기능을 가질 수있다. 그리고 그것은 언어가 작동하는 방식에 실제로는 맞지 않습니다.

+1

이것은 훌륭한 점입니다. 감사! –

1

다른 사람들이 말한 것처럼 처음에는 이름이 조회 된 다음 액세스 제한이 적용됩니다. 명시 적으로 원하는 메서드를 호출하여이 문제를 해결할 수 있습니다 (예 :

).
fb.Bar::Baz() 
+0

하지만 한정된 구문으로주의해야합니다. 두 가지 작업을 수행합니다. 1) 컨트롤 이름 조회 2) 동적 디스패치 사용 안 함 (이 특별한 경우는 아니지만 가능할 수 있음). – curiousguy