2011-01-10 2 views
10

상속으로 가득 찬 C++ 라이브러리가 있다고 가정합니다. 실제로 Derived 개체를 가리키고 DerivedBase을 상속 받았다는 것을 알았을 때 함수에 Base*이 주어졌습니다. 하지만 어떤 종류의 상속 (public/protected/private)인지는 알 수 없습니다. 또한 계층 구조에 가상 함수가 있는지 여부도 알 수 없습니다.static_cast 대 dynamic_cast

내가 사용해야 캐스트 소스 코드/문서 BaseDerived의로 보지 않고이 상황, 을 감안할 때? 또는 다형성에 대한 보장을 위해 먼저 코드/문서를 참조해야합니까?

배경

내가 Qt를 4.7에서 QMainWindowchangeEvent 기능을 쓰고 있어요. changeEvent 함수는 QEvent*이 걸리므로 QEvent::type()을 알면 다른 형식으로 변환 할 수 있습니다. static_cast 또는 dynamic_cast을 사용해야하는지 궁금 해서요.

감사합니다.

+3

만약 당신이 사용하는 라이브러리가'protected' 상속을 사용한다면, 더 좋은 라이브러리를 찾을 때입니다. –

+0

이 질문은 도움이 될 수 있습니다 : http://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast –

+2

@ Zac : 소원 나는 의견을 downvote 수 있습니다. 해당 라이브러리가 무엇인지 모르는 경우 보호 된 상속이 해당 작업에 적합한 도구인지 여부를 어떻게 판단 할 수 있습니까? – Puppy

답변

17

static_cast을 사용하십시오. 을 입력하면 Base*Derived을 가리키고, static_cast을 사용합니다. dynamic_cast은 유용 할 때 을 가리킬 수 있습니다. MSDN에서

+1

이제 알게 될 것입니다. 그러나 그는 도서관을 사용하고 있으며 도서관이 제공 한 보증인이 없다고 확신하고 있습니다. 구현 세부 사항을 변경하지 않을 것입니다. 인터페이스는 Base *이므로 ** ALL **로 가정 할 수 있습니다. 그러므로 ** 반드시 dynamic_cast <>를 사용해야합니다. 그러면 가정이 나중에 유지되는지 확인할 수 있습니다. –

+0

@ Martin : 그건 내 문제가 아니라 그의 문제입니다. 만약 그가 실제로 파생물을 가리킨다는 것을 알고 있다면, 그 지식의 뿌리는 제가 대답 할 수있는 범위를 벗어납니다. – Puppy

+2

그는 그 사실을 알 수 없다. 그의 지식은이 특별한 경우의 시간 공간 좌표로 제한됩니다. 따라서 우리는 그가 알고있는 자신의 가정에서 OP가 잘못되었다는 점을 강조 할 필요가있다. 그는 현재 알고 있지만 지식은 미래로 이전 할 수 없습니다. 따라서 그가 틀렸기 때문에 static_cast는 잘못된 대답입니다 (OP가 정확하다면 정답입니다). 인터페이스가 파생되었다고 가정 할 수있는 유일한 시간은 파생 된 *을 반환 할 때입니다. 그렇지 않으면 Base *에서 파생 된 모든 항목을 반환 할 수 있습니다 (코드에 인터페이스가있는 이유). –

3

은 - 당신이 숫자 데이터 형식을 변환 할 때 일반적으로

당신은 수레에의 int 또는 int 치의에 열거으로 static_cast를 사용하여, 당신은 변환에 관련된 데이터 유형의 일부입니다. static_cast 변환은 dynamic_cast 변환과 달리 안전하지 않습니다. 왜냐하면 static_cast는 런타임 유형 검사를 수행하지 않기 때문에 dynamic_cast는 수행합니다. 모호한 포인터에 대한 dynamic_cast는 실패하고 static_cast는 아무 것도 잘못되지 않은 것처럼 반환합니다. 위험 할 수 있습니다. dynamic_cast 변환이 더 안전하지만 dynamic_cast는 포인터 또는 참조에서만 작동하며 런타임 유형 검사는 오버 헤드입니다.

더 많은 정보를 위해,이 link

8

의심, 당신은 dynamic_cast을 선호한다 확인하십시오. 느려질 수도 있지만 어쨌든 그 차이를 눈치 채지 못할 것입니다.

template <typename Derived, typename Base> 
Derived safe_static_cast(Base b) 
{ 
    assert((void*)dynamic_cast<Derived>(b) && "safe_static_cast failed!"); 
    return static_cast<Derived>(b); 
} 

또는 이에 해당하는 : 당신이 속도를해야하는 경우

는 다음 코드를 사용합니다.

아이디어는 디버그 빌드에서 실제로 생각했던 것임을 확인하고 빌드를 릴리스합니다. 모든 것이 이미 테스트되었습니다. 그렇지 않습니까?

+1

당신은'(void *)'캐스팅을 필요로하지 않습니다. –

+0

@ 유전자 : 그것은 추악합니다. :) 나는 참고 용으로 오버로딩하는 것을 피하려고했습니다. –