2017-12-06 15 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) - 私はコンパイラがそれらについて文句を言うと思います。 –

関連する問題