2012-11-11 3 views
3

죄송합니다. 이는 너무 고생했지만 숙제 문제와 관련이 있습니다. 나는 왜 내가 모든 주석을 제외하고 모든 일이 일어나는 지 이해한다. 누군가 C++이하는 일을 왜하는지 설명해 주시겠습니까?C++ 상속 및 메서드 오버로드 혼란

감사

#include <iostream> 

using namespace std; 

class X0 {}; 
class X1: public X0 {}; 
class X2: public X1 {}; 

class Y1 
{ 
public: 
    virtual void f(int v)  { cout << "Y1(int)" << endl; } 
    virtual void f(const X0 *x) { cout << "Y1(X0)" << endl; } 
    virtual void f(const X1 *x) { cout << "Y1(X1)" << endl; } 
}; 

class Y2: public Y1 
{ 
public: 
    virtual void f(const X0 *x) { cout << "Y2(X0)" << endl; } 
    virtual void f(const X1 *x) { cout << "Y2(X1)" << endl; } 
    virtual void f(const X2 *x) { cout << "Y2(X2)" << endl; } 
}; 

int main(int argc, char * argv[]) 
{ 
    X2 x2; X2 *X2Pointer = &x2; 
    Y2 y2; Y1 *Y1Pointer = &y2; 

    cout << "What is about to happen?" << endl; 
    //Y1 pointer points to a Y2 object. 
    //The Y2 class, upon being given an X2 pointer, should print Y2(X2) 
    Y1Pointer->f(X2Pointer); 
    cout << "Why did I just print Y2(X1)" << endl; 
    return 0; 
} 
+1

C++은 아무 것도하지 않습니다. 그 일을하는 사람 –

+1

이것은 최소한의 예와 거의 반대입니다. 우리는 당신이 이해하는 것을 시연 할 필요가 없습니다. 당신이하지 못하는 것에 대한 예입니다. –

답변

3

클래스 Y1f() 이러한 과부를 노출 : f()라는

class Y1: public Y0 { 
public: 
    virtual void f(int v)  { cout << "Y1(int)" << endl; } 
    virtual void f(const X0 *x) { cout << "Y1(X0)" << endl; } 
    virtual void f(const X1 *x) { cout << "Y1(X1)" << endl; } 
    // ... 
}; 

다른 모든 방법 Y0에서 상속이 숨겨져 있습니다. 컴파일러는 f()의 세 가지 오버로드에 오버로드 확인을 수행하고 f(const X1*) 최고의 일치하고이 함수를 호출하는 결론에 온다

Y1Pointer->f(X2Pointer); 

를 호출 할 때 즉,. 밝혀 졌 듯이 virtual 함수이며 Y2으로 재정의되고 Y2::f(const X1*)이 호출됩니다.

+0

내가 틀렸다면 정정 해주세요. 그러나 제가 수집하는 것은 이것입니다 : 컴파일러는 Y1 인 포인터 유형을 봅니다. 따라서 클래스 Y1에 들어가 f()가 가장 잘 일치하는지 찾습니다. 그런 다음 Y1이 가리키는 객체 유형을 Y2로 사용하고 Y2에서 Y1에서 결정된 것과 동일한 서명이있는 메서드를 호출합니다. –

+0

@ user1137940 : 그렇습니다. 첫 번째 단계에서 '가상'기능이 발견되면 어떻게 될까요? 나는 이것이 내가 나의 대답에서 말한 것이라고 생각한다. –

1

과부하 해결은 관련된 정적 유형을 기반으로 결정됩니다. Y1::f(const X1 *x)

Y1Pointer->f(X2Pointer) 경기, Y1Pointer의 정적 유형 Y1*이기 때문에 Y1::f(const X1 *x)X2* 매개 변수 f의 호출에 가장 적합한이기 때문이다.

Y1::f(const X1 *x)은 가상이므로 호출되는 실제 함수는 동적 유형에 따라 결정됩니다. Y1PointerY2을 가리키므로 Y2 버전의 f(const X1 *x)이 호출됩니다.

1

클래스 Y1에는 X2 *을 소비하는 과부하가 없습니다. Y1Pointer->f(X2Pointer) 함수 호출에 가장 잘 맞는 것은 Y1::f(X1 const *)입니다. Y1Pointer이 가리키는 실제 오브젝트가 Y1보다 더 많이 파생된다는 사실은 과부하가 선택되지 않았으므로 중요하지 않습니다.

0

다른 언급으로 문제는 기능 숨기기입니다. 그러나 당신이 할 수있는 것은 Y1 라인 using Y0::f; 안에 쓰면 원하는 결과를 얻을 수 있습니다.