C++では、オブジェクトの実際の型が同じクラスであるか、同じクラスでないか、派生型であるかどうかを知りたいと思います。これは、次のC#コードに似ています。C++での型チェック
Class Base
{
}
Class Child:Base
{
}
Base childObject = new Child();
If (childObject.GetType() == typeof(Child))
{
// do some code
}
ありがとう!
C++では、オブジェクトの実際の型が同じクラスであるか、同じクラスでないか、派生型であるかどうかを知りたいと思います。これは、次のC#コードに似ています。C++での型チェック
Class Base
{
}
Class Child:Base
{
}
Base childObject = new Child();
If (childObject.GetType() == typeof(Child))
{
// do some code
}
ありがとう!
これには2通りの方法があります。まず、typeid
演算子を使用できます。この演算子は、オブジェクトのタイプに関する情報を含むtype_info
構造体を返します。例:あなたがここにtypeid(*ptr)
ないtypeid(ptr)
を使用する必要が
Base* ptr = /* ... */
if (typeid(*ptr) == typeid(DerivedType)) {
/* ... ptr points to a DerivedType ... */
}
注意してください。 typeid(ptr)
を使用している場合、Base*
のオブジェクトはBase*
のオブジェクトになります。ポインターは、ポインターの種類にかかわらずタイプがBase*
なので、オブジェクトが返されます。注意すべき
重要な点は何ptr
ポイントでは正確DerivedType
としてであれば、これはチェックすることです。 ptr
がDerivedType
(おそらくEvenMoreDerivedType
)から派生した型のオブジェクトを指している場合、このコードは正しく動作しません。
もう少し頑強な種類のオブジェクトを指しているかどうかを確認する別の方法は、dynamic_cast
演算子を使用することです。 dynamic_cast
は、実行時にキャストが成功すると有効なポインタを返すチェックされた型キャストを実行し、そうでない場合はNULLを返します。たとえば、次のように
Base* ptr = /* ... */;
DerivedType* derived = dynamic_cast<DerivedType*>(ptr);
if (derived) {
/* ... points to a DerivedType ... */
}
これは追加の利点を持っているEvenMoreDerivedType
のようなものでptr
がポイント場合、キャストはまだDerivedType
からEvenMoreDerivedType
継承するため、成功すること。
最終的な思考として、あなたは時々、このようなコードを参照してください:
Base* ptr = /* ... */
if (DerivedType* derived = dynamic_cast<DerivedType*>(ptr)) {
/* ... points to a DerivedType ... */
}
これはif
文の本体へderived
ポインタをローカル・スコープと非ゼロ値はC++でtrue
に評価されているという事実を使用しています。私は個人的にはこれを読みやすく、エラーを起こしにくいが、忘れてはならないことは、あなたにとって最も簡単なものとなる。
希望すると便利です。
彼はオブジェクトが派生クラスの場合ではなく、ベースであるかどうかを知りたがっています。 – Puppy
ああ...私は、ポインタが子タイプを指していたかどうかをチェックしていた彼のサンプルコードによって混乱しました。有効なポイント。 – templatetypedef
typeid()を使用できます。
if (typeid(childObject) == typeid(ChildType)) {
}
これがtrueを返す場合は、それが子クラスであることがわかります。
ランタイムタイプID(RTTI)も有効にしてコンパイルする必要があります。 –
この**は、比較されるアイテムにvtblがある場合にのみ**機能します。 –
@Billy:それは本当ですが、基本クラスに仮想デストラクタを与えないのは誰ですか?仮想関数は事実上継承のポイントです。それを期待するのは不合理ではない。 – Puppy
DeadMGの答えは正しいです(私は何度もタイプIDを使用しました)が、私は後世のためにこれを投げ捨てると思いました。これを行うための「正しい」方法は、オブジェクト指向のビューです。
Class Base
{
virtual void something() {
// probably a no-op, but maybe some default stuff
}
}
Class Child : public Base
{
virtual void something() {
// do your child-specific code here
}
}
Base* childObject = new Child();
childObject->something(); // does the right thing
私はこの答えを秒です。 DeadMGの答えは正しいが、良いプログラミングの練習ではないかもしれない..! –
これは、オブジェクトの内部を何かしたいときにうまくいきます。一方、型に応じてオブジェクトを処理したい場合は、複雑で不便になります(二重のディスパッチと訪問者すべて) –
@ 7vies、しかし、この仮想メソッドのアプローチが最も効果的です維持するのが最も簡単です。 dynamic_castまたはtypeidが適切なアプローチである場合がありますが、それはまれなケースです。 – Tim
'childObject'のタイプは何ですか?実行時に型の概念が存在しないため、C++でこれを行う一般的な方法はありません。 –
質問: – Homam
質問を編集しますが、childObject.GetType()が何であるかについては何も述べていませんが、このコードは型の比較で分岐するのでひどいです。それがOOPが排除しなければならないものです。 –