Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type checking in C++

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!

like image 411
Homam Avatar asked Jan 03 '11 23:01

Homam


People also ask

What is type checking in C?

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.

What is type system and type checking?

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.

How many types of type checking are there in C++?

These terms describe the action of type checking, and both static type checking and dynamic type checking refer to two different type systems.

Why do we need type checking?

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.


1 Answers

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!

like image 94
templatetypedef Avatar answered Sep 20 '22 11:09

templatetypedef