C++では、オブジェクトの実際の型が同じクラスのものか、同じクラスのものか派生クラスのものかを知りたいです。これは、次のC#コードに似ています。
Class Base
{
}
Class Child:Base
{
}
Base childObject = new Child();
If (childObject.GetType() == typeof(Child))
{
// do some code
}
ありがとう!
これを行うには2つの方法があります。まず、typeid
演算子を使用できます。この演算子は、オブジェクトのタイプに関する情報を含むtype_info
構造体を返します。例えば:
Base* ptr = /* ... */
if (typeid(*ptr) == typeid(DerivedType)) {
/* ... ptr points to a DerivedType ... */
}
ここではtypeid(*ptr)
ではなくtypeid(ptr)
を使用する必要があることに注意してください。 typeid(ptr)
を使用する場合、ポインターはtype_info
のBase*
オブジェクトを取得します。これは、ポインターが何を指しているかに関係なくBase*
型を持っているためです。
注意すべき重要な点は、これはptr
が指しているものがexactly as DerivedType
であるかどうかをチェックすることです。 ptr
がDerivedType
から派生したタイプのオブジェクト(多分EvenMoreDerivedType
)を指している場合、このコードは正しく機能しません。
もう少し堅牢なタイプのオブジェクトを指しているかどうかを確認する別の方法は、dynamic_cast
演算子を使用することです。 dynamic_cast
は実行時にチェックされた型キャストを実行し、キャストが成功した場合は有効なポインタを生成し、それ以外の場合はNULLを生成します。例えば:
Base* ptr = /* ... */;
DerivedType* derived = dynamic_cast<DerivedType*>(ptr);
if (derived) {
/* ... points to a DerivedType ... */
}
これには、ptr
がEvenMoreDerivedType
を継承するため、EvenMoreDerivedType
がDerivedType
のようなものを指す場合でも、キャストが成功するという追加の利点があります。
最後に、次のようなコードが表示されることがあります。
Base* ptr = /* ... */
if (DerivedType* derived = dynamic_cast<DerivedType*>(ptr)) {
/* ... points to a DerivedType ... */
}
これは、derived
ポインターをif
ステートメントの本体にローカルでスコープし、C++ではゼロ以外の値がtrue
に評価されるという事実を使用します。私は個人的にこれが読みやすく、エラーが発生しにくいと思いますが、必ずあなたにとって最も簡単な方法で行ってください。
お役に立てれば!
DeadMGの答えは正しいですが(私はtypeidを何度も使用しました)、私は後世のためにそこに捨てると思いました。オブジェクト指向ビューからこれを行う「正しい」方法は次のとおりです。
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
Typeid()を使用できます。
if (typeid(childObject) == typeid(ChildType)) {
}
これがtrueを返す場合、それが子クラスであることがわかります。