c++ - When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?

ID : 223

viewed : 271

Tags : c++pointerscastingc++-faqc++

Top 5 Answer for c++ - When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?

vote vote


static_cast is the first cast you should attempt to use. It does things like implicit conversions between types (such as int to float, or pointer to void*), and it can also call explicit conversion functions (or implicit ones). In many cases, explicitly stating static_cast isn't necessary, but it's important to note that the T(something) syntax is equivalent to (T)something and should be avoided (more on that later). A T(something, something_else) is safe, however, and guaranteed to call the constructor.

static_cast can also cast through inheritance hierarchies. It is unnecessary when casting upwards (towards a base class), but when casting downwards it can be used as long as it doesn't cast through virtual inheritance. It does not do checking, however, and it is undefined behavior to static_cast down a hierarchy to a type that isn't actually the type of the object.

const_cast can be used to remove or add const to a variable; no other C++ cast is capable of removing it (not even reinterpret_cast). It is important to note that modifying a formerly const value is only undefined if the original variable is const; if you use it to take the const off a reference to something that wasn't declared with const, it is safe. This can be useful when overloading member functions based on const, for instance. It can also be used to add const to an object, such as to call a member function overload.

const_cast also works similarly on volatile, though that's less common.

dynamic_cast is exclusively used for handling polymorphism. You can cast a pointer or reference to any polymorphic type to any other class type (a polymorphic type has at least one virtual function, declared or inherited). You can use it for more than just casting downwards – you can cast sideways or even up another chain. The dynamic_cast will seek out the desired object and return it if possible. If it can't, it will return nullptr in the case of a pointer, or throw std::bad_cast in the case of a reference.

dynamic_cast has some limitations, though. It doesn't work if there are multiple objects of the same type in the inheritance hierarchy (the so-called 'dreaded diamond') and you aren't using virtual inheritance. It also can only go through public inheritance - it will always fail to travel through protected or private inheritance. This is rarely an issue, however, as such forms of inheritance are rare.

reinterpret_cast is the most dangerous cast, and should be used very sparingly. It turns one type directly into another — such as casting the value from one pointer to another, or storing a pointer in an int, or all sorts of other nasty things. Largely, the only guarantee you get with reinterpret_cast is that normally if you cast the result back to the original type, you will get the exact same value (but not if the intermediate type is smaller than the original type). There are a number of conversions that reinterpret_cast cannot do, too. It's used primarily for particularly weird conversions and bit manipulations, like turning a raw data stream into actual data, or storing data in the low bits of a pointer to aligned data.

C-style cast and function-style cast are casts using (type)object or type(object), respectively, and are functionally equivalent. They are defined as the first of the following which succeeds:

  • const_cast
  • static_cast (though ignoring access restrictions)
  • static_cast (see above), then const_cast
  • reinterpret_cast
  • reinterpret_cast, then const_cast

It can therefore be used as a replacement for other casts in some instances, but can be extremely dangerous because of the ability to devolve into a reinterpret_cast, and the latter should be preferred when explicit casting is needed, unless you are sure static_cast will succeed or reinterpret_cast will fail. Even then, consider the longer, more explicit option.

C-style casts also ignore access control when performing a static_cast, which means that they have the ability to perform an operation that no other cast can. This is mostly a kludge, though, and in my mind is just another reason to avoid C-style casts.

vote vote


  • Use dynamic_cast for converting pointers/references within an inheritance hierarchy.

  • Use static_cast for ordinary type conversions.

  • Use reinterpret_cast for low-level reinterpreting of bit patterns. Use with extreme caution.

  • Use const_cast for casting away const/volatile. Avoid this unless you are stuck using a const-incorrect API.

vote vote


(A lot of theoretical and conceptual explanation has been given above)

Below are some of the practical examples when I used static_cast, dynamic_cast, const_cast, reinterpret_cast.

(Also referes this to understand the explaination : http://www.cplusplus.com/doc/tutorial/typecasting/)

static_cast :

OnEventData(void* pData)  {   ......    //  pData is a void* pData,     //  EventData is a structure e.g.    //  typedef struct _EventData {   //  std::string id;   //  std:: string remote_id;   //  } EventData;    // On Some Situation a void pointer *pData   // has been static_casted as    // EventData* pointer     EventData *evtdata = static_cast<EventData*>(pData);   ..... } 

dynamic_cast :

void DebugLog::OnMessage(Message *msg) {     static DebugMsgData *debug;     static XYZMsgData *xyz;      if(debug = dynamic_cast<DebugMsgData*>(msg->pdata)){         // debug message     }     else if(xyz = dynamic_cast<XYZMsgData*>(msg->pdata)){         // xyz message     }     else/* if( ... )*/{         // ...     } } 

const_cast :

// *Passwd declared as a const  const unsigned char *Passwd   // on some situation it require to remove its constness  const_cast<unsigned char*>(Passwd) 

reinterpret_cast :

typedef unsigned short uint16;  // Read Bytes returns that 2 bytes got read.   bool ByteBuffer::ReadUInt16(uint16& val) {   return ReadBytes(reinterpret_cast<char*>(&val), 2); } 
vote vote


It might help if you know little bit of internals...


  • C++ compiler already knows how to convert between scaler types such as float to int. Use static_cast for them.
  • When you ask compiler to convert from type A to B, static_cast calls B's constructor passing A as param. Alternatively, A could have a conversion operator (i.e. A::operator B()). If B doesn't have such constructor, or A doesn't have a conversion operator, then you get compile time error.
  • Cast from A* to B* always succeeds if A and B are in inheritance hierarchy (or void) otherwise you get compile error.
  • Gotcha: If you cast base pointer to derived pointer but if actual object is not really derived type then you don't get error. You get bad pointer and very likely a segfault at runtime. Same goes for A& to B&.
  • Gotcha: Cast from Derived to Base or viceversa creates new copy! For people coming from C#/Java, this can be a huge surprise because the result is basically a chopped off object created from Derived.


  • dynamic_cast uses runtime type information to figure out if cast is valid. For example, (Base*) to (Derived*) may fail if pointer is not actually of derived type.
  • This means, dynamic_cast is very expensive compared to static_cast!
  • For A* to B*, if cast is invalid then dynamic_cast will return nullptr.
  • For A& to B& if cast is invalid then dynamic_cast will throw bad_cast exception.
  • Unlike other casts, there is runtime overhead.


  • While static_cast can do non-const to const it can't go other way around. The const_cast can do both ways.
  • One example where this comes handy is iterating through some container like set<T> which only returns its elements as const to make sure you don't change its key. However if your intent is to modify object's non-key members then it should be ok. You can use const_cast to remove constness.
  • Another example is when you want to implement T& SomeClass::foo() as well as const T& SomeClass::foo() const. To avoid code duplication, you can apply const_cast to return value of one function from another.


  • This basically says that take these bytes at this memory location and think of it as given object.
  • For example, you can load 4 bytes of float to 4 bytes of int to see how bits in float looks like.
  • Obviously, if data is not correct for the type, you may get segfault.
  • There is no runtime overhead for this cast.
vote vote


Does this answer your question?

I have never used reinterpret_cast, and wonder whether running into a case that needs it isn't a smell of bad design. In the code base I work on dynamic_cast is used a lot. The difference with static_cast is that a dynamic_cast does runtime checking which may (safer) or may not (more overhead) be what you want (see msdn).

Top 3 video Explaining c++ - When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?