In C++, I want to know whether the actual type of the object is from the same class, not the same class or a derived one. This is similar to the following C# code:
Class Base { } Class Child:Base { } Base childObject = new Child(); If (childObject.GetType() == typeof(Child)) { // do some code }
Thanks!
Type checking is the process of verifying and enforcing constraints of types in values. A compiler must check that the source program should follow the syntactic and semantic conventions of the source language and it should also check the type rules of the language.
A type system is a set of rules assigning type expressions to different parts of the program. Type systems can (usually) be implemented in a syntax-directed way. The implementation of a type system is called a type checker.
These terms describe the action of type checking, and both static type checking and dynamic type checking refer to two different type systems.
Every value generated in a program is associated with a type. In a strongly typed language, the language implementation is required to check the types of operands in order to ensure that nonsensical operations, like dividing the integer 5 by the string ``hello'', are not performed.
There are two ways that you can do this. First, you can use the typeid
operator, which returns a type_info
structure containing information about the type of the object. For example:
Base* ptr = /* ... */ if (typeid(*ptr) == typeid(DerivedType)) { /* ... ptr points to a DerivedType ... */ }
Notice that you have to use typeid(*ptr)
and not typeid(ptr)
here. If you use typeid(ptr)
, then you'll get back a type_info
object for Base*
, since the pointer has type Base*
regardless of what it points at.
An important point to note is that this will check if what ptr
points at is exactly a DerivedType
. If ptr
is pointing at an object of a type derived from DerivedType
(maybe an EvenMoreDerivedType
), this code will not work correctly.
An alternative way of checking whether you are pointing at an object of some type that is a bit more robust is to use the dynamic_cast
operator. dynamic_cast
performs a checked typecast at runtime that will yield a valid pointer if the cast succeeds and nullptr
otherwise. For example:
Base* ptr = /* ... */; auto* derived = dynamic_cast<DerivedType*>(ptr); if (derived) { /* ... points to a DerivedType ... */ }
This has the added advantage that if ptr
points at something like an EvenMoreDerivedType
, the cast will still succeed because EvenMoreDerivedType
inherits from DerivedType
.
As a final thought, you sometimes see code like this:
Base* ptr = /* ... */ if (auto* derived = dynamic_cast<DerivedType*>(ptr)) { /* ... points to a DerivedType ... */ }
This locally-scopes the derived
pointer to the body of the if
statement and uses the fact that nonzero values evaluate to true
in C++. I personally find this easier to read and less error-prone, but by all means go with what's easiest for you.
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With