Cpp Casts (static, dynamic, const, reinterpret)

Cpp Casts (static, dynamic, const, reinterpret)

Tags
c++
Published
April 8, 2020
Author
Chris Chan
There are four main forms of cast in C++: static_castdynamic_castconst_cast and reinterpret_cast. This article explores when and how you should use each.

Static Cast

This is the most commonly used form of cast. It is used to convert between ordinary types. For instance, converting int to float or vice versa.
A common use case of static_cast would be if you needed to pass a certain primitive type to a function, but your variables are of the wrong type.
 
void myFunction(double x) { ... } int x = 3; // x is stored as int myFunction(static_cast<double>(x)); // static_cast x to double
This form of casting is heavily preferred over traditional C style of casting:
 
myFunction((double)x); // C style of casting myFunction(static_cast<double>(x)); // Cpp style of casting
There are two main reasons for this.
  • 1. static_cast adds a compile time check for our casts. In the example below we try to cast a dynamically allocated into to a char*, which does not makes sense. Line 1 will compile, while line 2 will not compile.
char* c = (char*)new int( 3 ); //(1) char* c1 = static_cast<char*>( new int( 3 ) ); //(2)
 
  • 2. It is much easier to search static_cast in your code.
 

Dynamic Cast

Unlike static_castdynamic_cast involves runtime checking. At runtime, it will safely cast pointers/references up/down/sideways in your inheritance heirarchy. A failed cast on a pointer type will return a nullptr and a failed cast on a reference type will throw an std::bad_cast exception.
This cast only works on polymorphic types: any class with at least one virtual method/destructor/base class.
This cast is commonly used in polymorphic situations in which you have a pointer/reference to a base class, but you would like to perform a derived class operation. static_cast can also be used in these scenarios, but they will not provide the same runtime checks.
 
class Base { public: virtual ~Base() {} }; class Derived : public Base {}; Base *base = new Derived; Derived *derived = dynamic_cast<Derived*>(base);

Const Cast

This cast is used to remove the constness of a variable. For instance, it can be used to cast away the const in a const pointer so that it can be passed into a function that does not accept a const pointer.
If you modify a value that is initially declared const, the output will be undefined. That is, if void someFunction(SomeObject *obj) modifies obj, then we will have undefined behavior.
 
void someFunction(SomeObject *obj) { ... } const SomeObject *const_ptr = createConstObjectPtr(); SomeObject *ptr = const_cast<SomeObject*>(obj); someFunction(ptr);

Reinterpret Cast

Reinterpret cast can be used to reinterpret the type of a variable. It is generally used to cast a pointer of one type to another type regardless of the relation between the two types.
 
int* p = new int(65); char* ch = reinterpret_cast<char*>(p);

Summary

static_cast -> convert between ordinary types
dynamic_cast -> use for polymorphic types
const_cast -> cast away const
reinterpret_cast ->reinterpret the type
Sources: