回答:
dynamic_castはトリックを行う必要があります
TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);
dynamic_cast
キーワードは、キャストの妥当性を確保するために、ランタイムチェックを行う、別のポインタまたは参照型からデータムをキャストします。
実際のオブジェクトのタイプではないタイプへのポインターにキャストしようとすると、キャストの結果はNULLになります。実際のオブジェクトのタイプではないタイプへの参照にキャストしようとすると、キャストによってbad_cast
例外がスローされます。
dynamic_castを機能させるには、Baseクラスに少なくとも1つの仮想関数があることを確認してください。
ウィキペディアのトピック実行時の型情報
RTTIは、ポリモーフィックなクラスでのみ使用できます。つまり、クラスには少なくとも1つの仮想メソッドがあります。実際には、これは制限ではありません。基本クラスには仮想デストラクタが必要であり、派生クラスのオブジェクトがベースポインタから削除された場合に適切なクリーンアップを実行できるようにする必要があるためです。
dynamic_cast
変換できない場合はスローしませんか?スローを生成せずにそれを行う方法はありますか?
A* aptr = dynamic_cast<A*>(ptr);
//これはこのようになるはずではありません
uint8_t*
か?つまり、私はそれをチェックすることができuint32_t* x = dynamic_cast<uint32_t*>(p)
、どこp
でuint8_t*
?(私は罰則違反のテストを見つけようとしています)。
問題の説明には動的キャストが最適ですが、クラスタイプを次のように検索できることを追加しておきます。
#include <typeinfo>
...
string s = typeid(YourClass).name()
11MyClass
。分解するには、のABI拡張ライブラリを使用できますcxxabi.h
。これはあなたを与えるabi::__cxa_demangle
あなたの本当の名前与えるであろう
完全にするために、私はRobocideからビルドをビルドし、typeid
name()を使用せずに単独で使用できることを指摘します。
#include <typeinfo>
#include <iostream>
using namespace std;
class A {
public:
virtual ~A() = default; // We're not polymorphic unless we
// have a virtual function.
};
class B : public A { } ;
class C : public A { } ;
int
main(int argc, char* argv[])
{
B b;
A& a = b;
cout << "a is B: " << boolalpha << (typeid(a) == typeid(B)) << endl;
cout << "a is C: " << boolalpha << (typeid(a) == typeid(C)) << endl;
cout << "b is B: " << boolalpha << (typeid(b) == typeid(B)) << endl;
cout << "b is A: " << boolalpha << (typeid(b) == typeid(A)) << endl;
cout << "b is C: " << boolalpha << (typeid(b) == typeid(C)) << endl;
}
出力:
a is B: true
a is C: false
b is B: true
b is A: false
b is C: false
あなたの説明は少し混乱しています。
一般的に言えば、一部のC ++実装にはそのためのメカニズムがありますが、型について尋ねる必要はありません。代わりに、Aへのポインターでdynamic_castを実行することになっています。これにより、実行時に、Aへのポインターの実際の内容がチェックされます。Bがある場合、Bへのポインタを取得します。それ以外の場合、例外またはnullを取得します。
オーバーロードされた関数を使用します。dynamic_castまたはRTTIサポートさえ必要ありません:
class A {};
class B : public A {};
class Foo {
public:
void Bar(A& a) {
// do something
}
void Bar(B& b) {
Bar(static_cast<A&>(b));
// do B specific stuff
}
};
ブーストライブラリにアクセスできる場合、おそらくtype_id_with_cvr()関数が必要です。const 、volatile、および&&修飾子を削除せずにデータ型を提供できます。C ++ 11の簡単な例を次に示します。
#include <iostream>
#include <boost/type_index.hpp>
int a;
int& ff()
{
return a;
}
int main() {
ff() = 10;
using boost::typeindex::type_id_with_cvr;
std::cout << type_id_with_cvr<int&>().pretty_name() << std::endl;
std::cout << type_id_with_cvr<decltype(ff())>().pretty_name() << std::endl;
std::cout << typeid(ff()).name() << std::endl;
}
これがお役に立てば幸いです。