ポリモーフィック型へのポインタがありますp
。type_info
同じ階層のどこかにクラスのがありますti
。
を比較するだけtypeid(*p) == ti
で、ポインタがそのクラスの直接インスタンスを指しているかどうかを実行時にテストできます。
C ++のRTTIを使用して、そのクラスから*p
継承するかどうかをテストする同様の方法はありますか?
標準のC++だけでこれを行う方法はありません。Itanium C ++ ABI 1を備えた実装を使用している場合は、次のように 実行できます。
#include <iostream>
#include <typeinfo>
#include <cxxabi.h>
#include <memory>
class base {
protected:
base() {
}
public:
static bool check(const std::type_info& p) {
// Find the real type_info for single inheritance non virtual
const __cxxabiv1::__si_class_type_info* test = dynamic_cast<const __cxxabiv1::__si_class_type_info*>(&p);
return test ? typeid(base) == *test->__base_type : false;
}
virtual ~base() {}
};
class der : public base {
};
class foo {};
int main() {
der d;
foo f;
std::cout << base::check(typeid(d)) << "\n";
std::cout << base::check(typeid(f)) << "\n";
}
ここでは、型に仮想的に継承されていない単一のベースがあるため、これが機能します。注意して同様の方法で、より多くのケースをサポートできますdynamic_casts
。
これはこれらの特定の状況下で可能ですが、間違った問題を解決していると思います-aに基づくソリューションstd::map
はより移植性が高く、このような実装の詳細に依存することを回避します。
1紛らわしい名前ですが、Itaniumだけでなく、驚くほど大きなコンパイラ/アーキテクチャリストです。
dynamic_cast<>
はい、その目的で使用できます。にキャストしようとするとBase*
、実行時チェックが実行され、クラスが実際に派生しているBase
か(または直接Baseであるか)が確認されます。失敗した場合は、をdynamic_cast<>
返しますnullptr
。例 :
struct Base {
virtual ~Base() {}
};
struct AnotherBase {
virtual ~Base() {}
};
struct Derived : Base {};
Base * basePtr = new Base();
Base * derivedPtr = new Derived();
AnotherBase * anotherBasePtr = new Base();
// is derivedPtr a pointer to a class derived from AnotherBase ?
AnotherBase* test2 = dynamic_cast<AnotherBase*>(derivedPtr); // test2 == nullptr
// is basePtr a pointer to a class derived from Derived ?
Derived * test3 = dynamic_cast<Derived*>(basePtr); // test3 == nullptr
サイドノード:
がポインタdynamic_cast<>
の変換に使用される場合、または変換されたポインタのいずれかを返します。nullptr
ただし、が参照dynamic_cast<>
の変換に使用されると、失敗した場合に例外がスローされます。
のランタイムチェックはdynamic_cast<>
、ポリモーフィックタイプでのみ可能です。Baseに仮想関数が含まれていない場合(=非多型)、を安全にに変換することはできませBase*
んDerived*
。
Flexoに感謝します。私はかなり前からC++ABIを研究してきました。1時間の作業の後、私はこのデモを手に入れました:http: //pastebin.com/j7DYY5ej。場合によっては継承をチェックするコードを次に示します。型に演算子==、!=、<、>、<=、>=を実装しました。このタイプ方程式の方法を改善し、プロジェクトで使用することを計画しています。LinuxではG++4.8を使用したことに注意してください。