8

Javaのinstanceofに相当する最新のC++ 11が何であるかを知りたいです。このSO の投稿を見たことがありますが、かなり古く、C++11 でよりモダンで優れたソリューションがあるかどうか疑問に思っていましたか?

手動の列挙型クラスに頼らなくても、スイッチ構造を使用できる可能性があることを願っていました。

class A {

};

class B : public A {

}

class C : public A {

}

on_event(A& obj)
{
    switch (obj) {
       case A:
       case B:
       case C:
    }
}

私の基本クラスには、仮想メソッドまたは関数がありません。私はパーサーの式ツリーを表しています。基本クラスは、Haskell/OCaml の ADT のような単なるポリモーフィック ホルダーです。

4

5 に答える 5

12

同じ答えが今でも当てはまり、C++ では常に次のようになっています。

if (C * p = dynamic_cast<C *>(&obj))
{
    // The type of obj is or is derived from C
}
else
{
    // obj is not a C
}

この構造はA、多態的である必要があります。つまり、仮想メンバー関数を持つ必要があります。

また、この動作は比較とは異なることに注意してくださいtypeid(obj) == typeid(C)。後者は正確な型同一性をテストするのに対し、動的キャストは Java の と同様instanceofに、ターゲット型が最も派生したオブジェクトの型の基本クラスであることをテストするだけだからです。

于 2014-10-12T12:54:58.650 に答える
0

C++ では、プレーン オールド データ (POD) には実行時の型情報がありません。説明されているすべてのクラスは正確に 1 バイトを取り、空の基本クラスの最適化を使用するどのコンパイラでも同一の実行時表現を持ちます。

そのため、あなたが望むことはできません。

基本クラスに仮想デストラクタを追加すると、RTTI とdynamic_castサポートが追加されます。

派生クラスごとに異なる方法で初期化されるenumorフィールドをベースに追加することも機能します。int

さらに別のオプションは、テンプレート関数を作成し、次のようにポインターを保存することです。

using my_type_id=void(*)();
template<class>void get_my_type_id_helper(){};
template<class T> my_type_id get_my_type_id(){return get_my_type_id_helper<T>;}

my_type_id次に、適切に初期化されたinを格納しAます。これは RTTI の再発明であり、より多くの機能が必要になると、C++ RTTI オーバーヘッドに近づきます。

C++ では、要求したものに対してのみ料金を支払います。RTTI を使用せずにクラスを要求して、それを取得できます。

RTTI はランタイム タイプ情報です。POD は単純な古いデータであり、C++03 用語です。多くのクラスは POD ではありません。簡単な方法は、virtualデストラクタを追加することです。C++11 には、よりきめ細かい標準レイアウトと集計用語があります。

技術的には、RTTI と POD は相反するものではありません。POD ではない RTTI のないクラスがあります。

MSVC には RTTI を生成しないオプションがあり、そのアグレッシブな Comdat フォールディングは、上記の手動 RTTI を壊す可能性があることに注意してください。どちらの場合も標準に違反しています。

于 2014-10-12T22:34:29.040 に答える
-1

(vtables を持つクラスのインスタンスのポインターを操作するのではなく) コンパイル時に既知の型に制限したい場合、C++11 以降にはinstanceof同等のものがあります: std::is_base_ofです。

std::is_convertiblestd:: is_sameもチェックしてください。

于 2014-10-12T13:26:32.973 に答える