2012-09-06 10 views
2

파생 클래스의 포인터를 상속 한 후에도 파생 클래스의 가상 메서드가 여전히 호출됩니다.이 메서드는 슬라이스가 발생 했어야했기 때문에 잘못되었습니다. 이 코드의 문제점에 대해 말씀해 주시겠습니까?파생 클래스의 가상 메서드가 업 캐스팅 후에 호출되는 이유는 무엇입니까?

class Base 
{ 
public: 
    virtual void Hello() { cout << "Hello Base" << endl; } 
}; 

class Derived: public Base 
{ 
public: 
    void Hello() { cout << "Hello Derived" << endl; } 
}; 

int main() 
{ 
    Derived* der = new Derived; 
    Base* base = dynamic_cast<Base*> (der); 
    if (base) base->Hello(); 
} 

출력 : 안녕하세요 파생

+1

다형성이 없으면 작동하지 않습니다. 동적 유형을 알 필요가 없으며 (여전히 파견 중임) 여기서 중요한 점이 있습니다. – Thilo

+0

'Base'는 non-virtual * base * 클래스이기 때문에 동적 캐스트는 무의미합니다. 어쨋든, 기본 함수를 호출하고 싶다면'der-> Base :: Hello();'라고 말할 수 있습니다. –

+2

여기에 슬라이스가 없습니다. –

답변

3

Base의 값으로 작업하지 않았으므로 슬라이스가 발생하지 않았습니다. 단지 포인터 일뿐입니다.

이 슬라이스 원인이 :

Base base = *der; 

을하지만 당신은 함수를 호출하고 역동적 인 파견을 억제하려는 경우, 당신은이 작업을 수행 할 수 있습니다

base->Base::Hello(); 

기능을 정적으로 지정 전화. 물론 der에서도 작동합니다. 물론 중간자는 피하십시오.


dynamic_cast은 여기에 필요하지 않습니다. 암시 적으로 업 캐스팅 할 수 있습니다. 이는 컴파일 타임에 쉽게 검증 할 수 있기 때문입니다. 다운 캐스트하려면 static_cast을 사용할 수 있지만 이것이 실제로 올바른지 확인하는 것은 사용자의 몫입니다. dynamic_cast은 그저 확인 된 버전 일뿐입니다.

+0

슬라이스가 발생할 때를 지적 해 주셔서 감사합니다. 나는 그것을 잘못 이해했다. 그리고 비록 그것이 실제로 무엇이든간에 기본 클래스 포인터와 객체로 작업 할 때마다 일어났지만 – rightaway717

2

포인터 캐스팅은 컴파일시에 안전하다 정적 타입 시스템에 관한 것입니다. 예 : 캐스팅은 컴파일러에게 "나를 믿어"라고 말하고있다. 런타임에는 아무런 영향이 없습니다. dynamic_cast와 같은 더 멋진 캐스트 작업은 런타임 검사를 제공하지만 (이해가되지 않는 한이 작업을 수행하지 마십시오.) 그래도 다형성에 영향을 미치지는 않습니다. 단지 "신뢰할 수있는"자격이 있습니다. 정신 나간 것.

다형성은 런타임에 올바른 일을하는 것에 관한 것입니다. 포인터를 통해 가상 메서드를 호출하면 개체 인스턴스에 대해 올바른 작업이 실행됩니다.

C++에서는 :: 연산자를 사용하여 특정 해상도를 요청할 수 있지만 일반적으로 구현 세부 정보 용으로 예약되어 있습니다.

+0

여기서 static_cast를 사용하면 도움이 될까요? 내가 시도했기 때문에 작동하지 않았다. 여전히 파생 클래스의 메서드가 호출되었습니다. 그래서 기본 클래스 메쏘드를 호출하기 원한다면, 나는 그것을 할 수있는 유일한 방법이있다 : - 연산자 :? – rightaway717

+0

오른쪽 : :: 유일한 선택입니다 –

관련 문제