dynamic_cast<> vs. std::is_base_of<>

Written by on May 9, 2020 in C++, Programming with 0 Comments

In the last article, we looked at the std:is_base_of<T1, T2> type trait. One question that a reader asked since that article appeared is “How does is_base_of<> differ from the dynamic_cast<> operator?”

Good question! In today’s post let me try to address the key differences between the two.

I am not going to cover the dynamic_cast<> operator in detail here. I urge you to go through the primary reference.

One of the common uses of dynamic_cast<> operator is to “safely” cast a pointer to base class type to a pointer to derived class type, provided it is valid. This might require the use of run-time type information (RTTI). 

Contrast this with is_base_of<>. This works with type names and not object references. To get a better idea, feel free to go through the earlier post.

Let us look at 4 different cases comparing dynamic_cast<> and is_base_of<>.

Case -1: Working with Classes

dynamic_cast<> can only work with class types, not primitive types. That is not a restriction in the case of is_base_of<>. See the following example:

Case-1

Case-1

You can see that dynamic_cast<> will not accept a non-class argument (line 15). 

Case-2: Non-polymorphic Class Hierrachy

dynamic_cast<> expects the argument to refer to a polymorphic class class, i.e., one that has at least one virtual function. The example below illustrates this point.

Case-2

Case-2

is_base_of<> does not have this limitation.

Case-3: Polymorphic Class Hierarchy

This is the common use case for dynamic_cast<> operator. Go through the following example.

Case-3

Case-3: Polymorphic Hierarchy

This shows how dynamic_cast<> uses RTTI to convert a pointer from base class to derived class pointer. In the case of invalid conversion, it returns NULL.

The type trait is_base_of<> works with types and not actual objects.

Case-4: Class Hierarchy with Twists!

As the final example, let us consider a class hierarchy that uses protected derivation and also multiple derivation of a common base class. 

Case-4: Complex Hierarchy

Case-4: Complex Hierarchy

Notice that class R is derived from Q using “protected” mode. Due to this, methods outside of R (global functions or methods of any class not derived from R) cannot access any member of Q via R instance. Interestingly, because of the non-public derivation,  dynamic_cast<> fails in line 18 by returning NULL.

Likewise, class S derives from P twice, via Q and R. This results in S object having two instances of P inside it. That is why, in lines 39-40, we first convert to void * then convert to P *. Of course, we get a run-time exception when we convert back to derived class through dynamic_cast<>.

It is possible to consider some minor variations of the above examples, but I think you now have a good understanding of the difference between dynamic_cast<> and is_base_of<>.

The example programs can be downloaded from here. I used Visual Studio 2019 (64 bit), Version 16.5.4 to test these examples.

Have a nice weekend!

Tags: , , ,

Subscribe

If you enjoyed this article, subscribe now to receive more just like it.

Subscribe via RSS Feed

Leave a Reply

Your email address will not be published.

Top