2017-12-06 5 views
1

기본 클래스에 대한 포인터가 (typeid을 사용하는) 어떤 유형인지 먼저 확인하면 성능을 저해하기 위해 reinterpret_cast을 수행하는 것이 유효합니까?typeid 검사가 유효 한 후에 reinterpret_cast를 사용하고 있습니까?

class Base { 
    virtual ~Base() {} 
}; 
class A : Base {}; 
class B : Base {}; 
... 
class Z : Base {}; 

나중에 곳 : 나는 그것을해야 생각하는

지금까지 내가 말할 수있는
void fn(Base & msg) { 
    const auto & tid = typeid(msg); 
    if (tid == typeid(A)) { 
     A * ptr = reinterpret_cast<A*>(&msg); 
    } else if (tid == typeid(B)) { 
     B * ptr = reinterpret_cast<B*>(&msg); 
    } ... 
    ... 
    } else if (tid == typeid(Z)) { 
     Z * ptr = reinterpret_cast<Z*>(&msg); 
    } 
} 

,이 코드는 잘 작동합니다. 그러나 운이 좋았거나 실제로 잘 정의 된 사용법 일 뿐이므로 궁금합니다. 이 방법으로 reinterpret_cast을 사용하십시오.

그리고 정상적인 다형성을 사용하기 전에 클래스를 변경할 수는 없으므로 클래스를 변경할 수는 없으므로 주위에이 방법을 만들어야합니다.

+2

전체 디자인은 여기 보이는 * 매우 * 깨진. 처음부터 바꿀 수없는 관련 자료를 다시 작성하는 것만으로도 충분히 가치가 있습니다. –

+2

'reinterpret_cast'는 vtable을 고려하지 않습니다. RTTI를 잃고 정의되지 않은 동작을 할 수 있습니다. 그래서 ** 유효하지 않습니다 **. – user1810087

+1

@BaummitAugen은 좋아하지만 다른 팀의 엉망진창을 고치고 있습니다. 슬프게도 예산을 다시 작성합니다 :/ – Paladin

답변

1

아니요, 동작은 여전히 ​​공식적으로 정의되지 않습니다.

이렇게하면 reinterpret_cast을 사용하면 엄격한 앨리어싱 규칙이 적용되지 않습니다.

성능이 인 경우 실제로이 문제가되는 경우 virtual 클래스를 모두 피하는 것이 좋습니다.

+0

대신 dynamic_cast를 사용하고 감사합니다. – Paladin

1

밧세바 (Bathsheba) 답변과 마찬가지로, 정의되지 않은 동작이 계속됩니다. 가상 상속이없는 경우

그러나 제대로 자식 클래스에 포인터를 상쇄하는 static_cast를 사용할 수 있습니다

void fn(Base & msg) { 
    const auto & tid = typeid(msg); 
    if (tid == typeid(A)) { 
     A * ptr = static_cast<A*>(&msg); 
    } else if (tid == typeid(B)) { 
     B * ptr = static_cast<B*>(&msg); 
    } else if (tid == typeid(Z)) { 
     Z * ptr = static_cast<Z*>(&msg); 
    } 
} 
+0

다중 상속 기본 클래스를 반복하지 않는 한이 옵션은 대부분의 경우 작동합니다 예 : IUnknown) - 나는 컴파일러가 그것들에 대해 불평 할 것이라고 생각한다. –

관련 문제