C++ 標準ライブラリ<typeinfo>

C++ では、<typeinfo>標準ライブラリの一部であり、ランタイム型識別(RTTI、Run-Time Type Identification)機能を提供します。RTTI により、プログラムは実行時にオブジェクトの型を決定できます。これは、typeid演算子とtype_infoクラスによって実装されます。

type_infoクラスは抽象基底クラスであり、型情報に関するインターフェースを提供します。各型にはそれに関連付けられたtype_infoオブジェクトがあり、typeid演算子を使用してアクセスできます。

構文

<typeinfo>関連する主な構文:

  • typeid演算子:オブジェクトの型情報を取得するために使用されます。
  • type_infoクラス:型情報を含むクラスです。

型情報クラスtype_info

typeinfoヘッダーファイルは、型情報に対するランタイムサポートを提供します。主に2つのコアコンポーネントが含まれています:std::type_infoクラスとtypeid演算子。typeinfoプログラムが実行時にオブジェクトの型情報を取得できるようにします。これは、ポリモーフィズムと型安全なコードで非常に役立ちます。以下に、typeinfoの詳細な説明を示します:

std::type_info クラス

std::type_infoクラスはtypeinfoヘッダーファイルのコアクラスであり、型を記述するために使用されます。型の情報を照会するための複数のメンバー関数を提供します。一般的なメンバー関数は次のとおりです:

  • const char* name() const noexcept;型名を指す C 文字列ポインタを返します。この名前は必ずしも人間が読める型名であるとは限らず、その形式はコンパイラの実装によって決まることに注意してください。

  • bool before(const std::type_info& rhs) const noexcept;何らかの順序に従って2つのtype_infoオブジェクトを比較し、現在のオブジェクトがrhsより前にあるかどうかを返します。

  • bool operator==(const std::type_info& rhs) const noexcept;2つのtype_infoオブジェクトが同じ型を表すかどうかを比較します。

  • bool operator!=(const std::type_info& rhs) const noexcept;2つのtype_infoオブジェクトが異なる型を表すかどうかを比較します。

typeid 演算子

typeid演算子は実行時に型情報を取得するために使用されます。typeidオブジェクト(ポリモーフィックな動作を持つポインタまたは参照)または型(オブジェクトのインスタンス化は不要)に対して使用できます。

  • typeid(object):std::type_infoオブジェクトを返し、objectの動的型を表します。もしobjectがポリモーフィック型(つまり仮想関数を含む)である場合、typeidはそのオブジェクトの実際の型を返します。
  • typeid(T):std::type_infoオブジェクトを返し、型を表しますT。

例

以下は、<typeinfo>を使った簡単な例です:

例

#include <iostream>
#include <typeinfo>

class Base {
public:
    virtual void show() { std::cout << "Base show" << std::endl; }
};

class Derived : public Base {
public:
    void show() override { std::cout << "Derived show" << std::endl; }
};

int main() {
    Base* basePtr = new Derived();
    Base* basePtr2 = new Base();

    std::cout << "Type of basePtr: " << typeid(*basePtr).name() << std::endl;
    std::cout << "Type of basePtr2: " << typeid(*basePtr2).name() << std::endl;

    if (typeid(*basePtr) == typeid(Derived)) {
        std::cout << "basePtr is of type Derived" << std::endl;
    } else {
        std::cout << "basePtr is not of type Derived" << std::endl;
    }

    delete basePtr;
    delete basePtr2;

    return 0;
}

出力結果:

Type of basePtr: 9Derived  // 注意:typeid的name()返回的类型名称可能因编译器而异
Type of basePtr2: 8Base     // 同上
basePtr is of type Derived

注意事項

  • RTTI 機能はコンパイラの実装に依存するため、typeid演算子が返す型名はコンパイラによって異なる場合があります。
  • RTTI を使用すると、実行時の型チェックが必要になるため、プログラムのパフォーマンスに一定の影響を与える可能性があります。
  • RTTI はポリモーフィック型、つまり仮想関数を持つクラスにのみ適用されます。

<typeinfo>実行時にオブジェクトの型を識別する方法を提供し、ポリモーフィズムと型安全性の実装に非常に役立ちます。ただし、開発者は不必要なパフォーマンスオーバーヘッドや潜在的な型エラーを避けるために、RTTI を慎重に使用する必要があります。

その他の拡張