# Type Casting in C++ 2023

There are several types of casts:

* Explicit casting: Using C-style casts (int)var
* Functional casts: std::function\<NewType>(var)
* Static casts: std::static\_cast\<NewType>(var)
* Reinterpret casts: std::reinterpret\_cast\<NewType>(var)
* Const casts: std::const\_cast\<NewType>(var)
* Dynamic casts: std::dynamic\_cast\<NewType>(var)

Among these:

* Static casts are used for safer casts that can be checked at compile-time
* Reinterpret casts do a raw conversion, disregarding type safety
* Const casts remove const qualifiers
* Dynamic casts use RTTI to cast to a base or derived type at runtime

When casting:

* The value is converted from its original type to the new type
* Data can be lost if the new type has a smaller size
* Constructors are not called - the raw bytes are reinterpreted

So in general, use the most specific cast that fulfills your requirements. More specific casts like static\_cast are safer than reinterpret\_cast. And avoid const\_cast when possible.

Hope this high-level explanation of type casting in C++ helps!

## std::static\_cast

std::static\_cast performs a cast that can be checked at compile-time for type safety. It should be used for safe and proper conversions between types.

For example:

```cpp
int x = 10;
double y = std::static_cast<double>(x);
```

Here we cast an `int` to a `double`, which is a safe conversion. The compiler can check this cast.

std::static\_cast can perform the following casts:

* Integral types to other integral types
* Pointer to pointer
* Pointer to integral
* Reference to reference
* Reference to integral
* Derived class to base class
* Base class to derived class (if we know the object is actually a derived class)

For example:

```cpp
Base* b = new Derived();

Derived* d = std::static_cast<Derived*>(b);  // Ok, we know b points to a Derived
```

So in summary, std::static\_cast performs type-safe casts that can be checked by the compiler. It should be preferred over C-style casts or reinterpret\_cast whenever possible.

Hope this explanation helps! Let me know if you have any other questions.

## std::reinterpret\_cast

Reinterpret casts perform a raw conversion between types, without performing any type checking. They should be used with caution.

For example:

```cpp
int x = 10;
double* y = reinterpret_cast<double*>(&x);
```

Here we cast the address of an `int` to a `double*` pointer. This is not a proper cast, but a raw reinterpretation of the integer's bytes as a double.

std::reinterpret\_cast can cast between any types, even those that would normally be disallowed:

* Integral to pointer
* Pointer to integral
* Unsigned to signed and vice versa
* Derived to base (or reverse) without regard to object's actual type

For example:

```cpp
Base* b = new Derived();

Base* b2 = reinterpret_cast<Base*>(b);  // Ok but unsafe!
```

Here we cast a Derived pointer to a Base pointer, without checking if the object is actually a Derived.

In summary, reinterpret\_cast performs an unsafe raw conversion between types, disregarding type safety.

It should only be used when absolutely necessary, as it can easily lead to undefined behavior and bugs.

Hope this explanation helps!

## std::const\_cast

std::const\_cast performs a cast that removes any const qualifiers from a type. This allows modifying a const object.

For example:

```cpp
const int x = 10;

int* y = const_cast<int*>(&x);

*y = 20; // Modifies a 'const int' - undefined behavior!
```

Here we:

* Define a const int
* Cast away the constness using const\_cast\<int\*>
* This gives us a non-const pointer to a const object
* When we modify this pointer, we modify a const object - causing undefined behavior.

const\_cast can cast:

* Pointer-to-const to pointer
* Reference-to-const to reference
* Const type to non-const type

In essence, it performs a const\_cast on the type.

const\_cast should be used with extreme caution, as modifying const objects leads to undefined behavior.

It is best to avoid the need for const\_cast whenever possible, by using const correctly.

In summary, const\_cast casts away const qualifiers from a type. But it does not actually make a const object non-const - it simply tricks the compiler. Modifying the resulting non-const reference or pointer to a const object is undefined.

Hope this explanation helps!

## std::dynamic\_cast

std::dynamic\_cast performs a cast at run-time using RTTI. It can cast between related types, even unrelated types that have a conversion.

For example:

```cpp
class Animal {};
class Dog : public Animal {};

Animal* a = new Dog();

Dog* d = dynamic_cast<Dog*>(a);  // OK, points to Dog object
```

Here we:

* Create a Dog object pointed to by an Animal pointer
* Cast to a Dog pointer using dynamic\_cast
* The cast succeeds at runtime because the object is actually a Dog

This works because:

* dynamic\_cast uses RTTI to determine the actual type at runtime
* It can only cast between related types in an inheritance hierarchy

Advantages over static\_cast:

* Can cast between unrelated types with a conversion function
* Returns nullptr if cast fails, rather than causing undefined behavior

So in summary, dynamic\_cast performs a safe run-time cast using RTTI. It checks if the cast is valid, and only performs it if so.

This allows casting between related types, even when the exact type is unknown at compile-time.

Hope this explanation helps! Let me know if you have any other questions regarding type casting in C++.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://adeshsingh.gitbook.io/programming/basic-c++-topics/type-casting-in-c++-2023.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
