C++
RTTI:実行時型情報
サーチ…
タイプの名前
typeid
返すstd::type_info
オブジェクトの.name()
メンバー関数を使用して、実行時に型の実装定義名を取得できます。
#include <iostream>
#include <typeinfo>
int main()
{
int speed = 110;
std::cout << typeid(speed).name() << '\n';
}
出力(実装定義):
int
dynamic_cast
dynamic_cast<>()
を関数として使用すると、継承階層( 主な説明 )をキャストダウンするのに役立ちます。
いくつかの派生クラスB
とC
で非多形性の仕事をしなければならないが、基本class A
受け取った場合は、次のように書く:
class A { public: virtual ~A(){} };
class B: public A
{ public: void work4B(){} };
class C: public A
{ public: void work4C(){} };
void non_polymorphic_work(A* ap)
{
if (B* bp =dynamic_cast<B*>(ap))
bp->work4B();
if (C* cp =dynamic_cast<C*>(ap))
cp->work4C();
}
typeidキーワード
typeid
キーワードは単項演算子で、オペランドの型が多型の型である場合、そのオペランドに関する実行時型の情報を生成します。 const std::type_info
型の左辺値を返します。トップレベルのCV資格は無視されます。
struct Base {
virtual ~Base() = default;
};
struct Derived : Base {};
Base* b = new Derived;
assert(typeid(*b) == typeid(Derived{})); // OK
typeid
は型に直接適用することもできます。この場合、最初のトップレベルの参照は取り除かれ、最上位のcv修飾は無視されます。したがって、上記の例は、 typeid(Derived{})
代わりにtypeid(Derived{})
typeid(Derived)
記述されている可能性があります。
assert(typeid(*b) == typeid(Derived{})); // OK
typeid
がポリモーフィックなクラス型ではない式に適用された場合、オペランドは評価されず、返される型情報は静的型用です。
struct Base {
// note: no virtual destructor
};
struct Derived : Base {};
Derived d;
Base& b = d;
assert(typeid(b) == typeid(Base)); // not Derived
assert(typeid(std::declval<Base>()) == typeid(Base)); // OK because unevaluated
C ++でどのキャストを使うか
継承階層内のポインタ/参照を変換するには、 dynamic_castを使用します。
通常の型変換にはstatic_castを使用します。
ビットパターンの低レベル再解釈のためにreinterpret_castを使用してください。極端な注意を払って使用してください。
const / volatileをキャストするためにconst_castを使用してください。あなたがconst-incorrect APIを使用して立ち往生しない限り、これを避けてください。