문제

Dynamic_cast 오류 처리와 관련된 모범 사례가 있습니까 (필요하지 않은 경우 사용하지 않는 경우는 제외)? 나는 어떻게 Null과 Bad_cast가 던질 수 있는지 궁금합니다. 둘 다 확인해야합니까? 그리고 내가 bad_cast를 잡거나 널을 감지하면 어쨌든 회복 할 수 없을 것입니다 ... 지금은 Assert를 사용하여 dynamic_cast가 널 값이 아닌지 확인했는지 확인합니다. 코드 검토 에서이 솔루션을 수락 하시겠습니까?

도움이 되었습니까?

해결책

만약 dynamic_cast ~해야 한다 성공하면 사용하는 것이 좋습니다 boost::polymorphic_downcast 대신, 이것은 다음과 같은 작은 일입니다.

assert(dynamic_cast<T*>(o) == static_cast<T*>(o));
return static_cast<T*>(o);

이렇게하면 디버그 빌드에서 오류를 감지하고 동시에 릴리스 빌드에서 런타임 오버 헤드를 피할 수 있습니다.

캐스트를 의심한다면 ~할 것 같다 실패하면 그것을 감지하고 싶다 dynamic_cast 그리고 참조 유형으로 캐스팅됩니다. 이 캐스트는 던질 것입니다 bad_cast 오류가 발생하면 프로그램을 중단합니다. (당신이 말했듯이, 당신이 어쨌든 회복하지 않을 것이라면 좋다)

T& t = dynamic_cast<T&>(o);
t.func(); //< Use t here, no extra check required

사용 dynamic_cast 0- 포인터가 컨텍스트에서 의미가있는 경우에만 포인터 유형으로. 당신은 그것을 사용하고 싶을 수도 있습니다 if 이와 같이:

if (T* t = dynamic_cast<T*>(o)) {
    t->func(); //< Use t here, it is valid
}
// consider having an else-clause

이 마지막 옵션을 사용하면 실행 경로가 dynamic_cast 반환 0.

귀하의 질문에 직접 답변하려면 : 나는 명시 적으로 제가 한 두 가지 첫 번째 대안 중 하나를 선호합니다. assert 코드에서 :)

다른 팁

BAD_CAST는 참조를 캐스팅 할 때만 발생합니다

dynamic_cast< Derived & >(baseclass)

포인터를 주조 할 때 NULL이 반환됩니다

dynamic_cast< Derived * >(&baseclass)

따라서 두 가지를 모두 확인할 필요가 없습니다.

주장은 받아 들일 수 있지만, 그것은 맥락에 크게 의존한다면, 다시 한 번, 그것은 거의 모든 주장에 사실입니다 ...

예 그리고 아니오.

boost::polymorphic_downcast<> 반드시 오류를 처리하는 좋은 옵션입니다 dynamic_cast<> 디버그 단계에서. 그러나 그것을 언급 할 가치가 있습니다 polymorphic_downcast<> 언제에 만 사용해야합니다 컴파일 시간에 통과 된 다형성 유형을 예측할 수 있습니다., 그렇지 않으면 dynamic_cast<> 대신 사용해야합니다.

그러나 순서 :

if (T1* t1 = dynamic_cast<T1*>(o)) 
{ }
if (T2* t2 = dynamic_cast<T2*>(o)) 
{ }
if (T3* t3 = dynamic_cast<T3*>(o)) 
{ }

정착 해야하는 매우 나쁜 디자인을 나타냅니다. 다형성 그리고 가상 기능.

때에 따라 다르지... ;-)

내가 정말로 기대했다면 dynamic_cast 예를 들어, 다른 사람과 다른 사람이 기본 클래스에 포인터 컨테이너에 다형성 유형을 추가하지 않으면 참조 캐스트와 함께 가서 std::bad_cast 내 응용 프로그램을 죽이십시오 - 정말로 할 일이 많지 않을 것입니다.

그러나 반드시 구현할 필요가없는 인터페이스에 노출 된 일부 기능에 대해 다형성 유형을 쿼리하는 경우 포인터 캐스트와 함께 가면 널이 오류가되지 않는 경우 ( 물론, 나는 능력을 기대했다 진짜 거기에 - 그러나 나는 처음에 참조 캐스트를 위해 갔다 ...)

나는 'It depends'대답에 동의하고 "우아한 황폐화"를 추가합니다. 캐스트가 어딘가에 실패하기 때문에 응용 프로그램이 실패 할 수있는 충분한 이유가 아닙니다 (그리고 사용자가 자신의 작업을 잃게됩니다). Asserts와 방어 프로그래밍의 조합을 권장합니다.

ptr = dynamic_cast<MyClass>(obj);
ASSERT(ptr);
if(ptr)
{
   // do stuff
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top