# Chapter 13 - Notes

## Casting

**Casting** is a mechanism that allows the programmer to temporarily or permanently change the interpretation of an object by the compiler.

Note that this does not imply that the object is changed, but rather the interpretation thereof.&#x20;

Operators that change the interpretation of an object are called **casting operators**.

### Motivation&#x20;

Consider the following real-world example: most modern C++ compilers support `bool` as a primitive type, though many libraries and programs were written a long time ago in C.&#x20;

The C programming language did not support `bool` as a primitive type, so the programmers had to rely on the use of an integral type to hold boolean-like data:

```cpp
typedef unsigned short boolean;

boolean isRaining(Day day) {
    if (...) {
        return 0;
    } else {
        return 1;
    }
}
```

If such code were to be used with a new application programmed and compiled using the latest C++ compiler, the programmer would have to find a way to convert such variables as a `bool`.&#x20;

The way to make this happen is by using **C-style casts**:

```cpp
bool raining = (bool)isRaining(today);
```

C++ introduces many new casting operators that behave differently. Some prefer the old C-style casts, while others prefer the newer operators introduced by C++.&#x20;

## Downsides of C-Style Casting&#x20;

Type safety is an important aspect of the C++ language, rightfully disallowing code like this:

```cpp
char* str = "ABCDEF";
int* intArray = str;
```

C-style casting however compromises this type safety by allowing anyone to force the compiler to interpret any variable as any type they wish:

```cpp
char* str = "ABCDEF";
int* intArray = (int*)str;  // Really bad! 
```

## C++ Casting Operators&#x20;

Despite the disadvantages, the concept of casting is still quite valuable, and there are legitimate use cases for it.&#x20;

C++ introduces four new casting operators specific to inheritance-based scenarios that did not exist in C:

* `static_cast`
* `dynamic_cast`
* `reinterpret_cast`
* `const_cast`

The usage of these casting operators is consistent to that of C-style casting:

```cpp
destination_type variable_name = cast_operator<destination_type>(object_to_cast);
```

### Static Cast&#x20;

Static casting has two use cases:

* Converting pointers between related types&#x20;
* Performing explicit type conversions for standard data types that would otherwise happen automatically or implicitly (recall conversion operators?)

`static_cast` implements a basic **compile-time check** to ensure that the pointer is being cast to a related type.&#x20;

Using `static_cast`, a pointer of a derived can be **upcasted** to a pointer of its base type, or can be **downcasted** to a pointer of its derived type.

```cpp
Base* base = new Derived();
Derived* derived = static_cast<Derived*>(base);  // OK!

Unrelated* unrelated = static_cast<Unrelated*>(base);  // NOT OK - compile error!
```

{% hint style="info" %}
Casting a pointer of a derived class to a pointer of a base class is called **upcasting**. This **can** be done without the use of any casting operators.

Casting a pointer of a base class to a pointer of a derived class is called **downcasting**. This **cannot** be done without the explicit use of a casting operator.
{% endhint %}

`static_cast` can make implicit casts explicit:

```cpp
double pi = 3.14159265;
int num = static_cast<int>(pi);
```

In the above example, the program would behave the same even without the casting operator. Its purpose here is merely to bring to the attention of other programmers that casting is occurring.

Such explicit casting is also necessary for objects who have defined conversion operators that have been marked as **explicit**.

#### Downsides&#x20;

`static_cast` only verifies that the pointer types being casted to and fro are related. It does not perform any **runtime checks**.&#x20;

The following bug will still compile:

```cpp
Base* base = new Base();
Derived* derived = static_cast<Derived*>(base);
```

The `derived` variable contains a partially constructed `Derived` object, because the underlying object is of type `Base`. As such, any calls to derived member functions will result in **undefined behaviour**.

### Dynamic Cast&#x20;

**Dynamic casting**, as the name implies, is the opposite of static casting, and performs the cast at **runtime** as opposed to at compile time.

The result of the `dynamic_cast` operation can be used to determine whether the attempt at casting the object to a desired type has been successful.&#x20;

```cpp
Base* base = new Derived();
// Downcasting 
Derived* derived = dynamic_cast<Derived*>(base);

if (derived == nullptr) {
    std::cout << "Cast was unsuccessful" << std::endl;
} else {
    std::cout << "Cast was successful" << std::endl;
    derived->derived_function();
}
```

As shown above, the result of a dynamic cast if not successful will return a `nullptr`. The result returns a pointer to the desired type, as with static casting, if the cast was successful.&#x20;

This is also known as **Runtime Type Identification** (RTTI) - which is to mean that the type of the underlying object held by a base type pointer can be identified at runtime.&#x20;

### Reinterpret Cast&#x20;

`reinterpret_cast` is the closest C++ casting operator to a C-style cast. It allows the programmer to cast an object of any type into another, regardless of whether the two types are related.&#x20;

It forces the reinterpretation of all the bytes of an object, as if it were of another type.&#x20;

This is useful for very low-level programming interfaces, where a function returns an array of bytes (`unsigned char*`) that could represent an arbitrary data structure.&#x20;

Reinterpret casting inherits all the benefits and downsides of C-style casting, and should **generally be avoided** unless completely necessary. &#x20;

### Const Cast&#x20;

`const_cast` allows one to remove the `const` access modifier on an object.&#x20;

If this sounds weird to you, then your understanding of `const` objects is well.&#x20;

Consider the following example:

```cpp
struct Box {
    // ...
    void display();  // This function is not marked const
};

void displayBox(const Box& box) {
    box.display();  // Compile error 
}
```

Now imagine that the source code for `Box` is elsewhere, and you have no control over it. In this situation the use of `const_cast` is helpful:

```cpp
void displayBox(const Box& box) {
    Box& refBox = const_cast<Box&>(box);
    box.display();  // OK!
}
```

Though using `const_cast` to invoke non-const functions should only be used as a last resort. You should ensure that whatever function you intend to invoke actually **does not mutate the state** of the object.

## Downsides of C++ Casting

### Redundant&#x20;

Most reasonable usage of `static_cast` is well covered by C-style casting, which has a much less verbose syntax:

```cpp
double pi = 3.142;
int num = static_cast<int>(pi);  
// or 
int num = (int)pi;
// or
int num = pi;
```

In all cases, the same result is achieved, with `num` being 3.&#x20;

```cpp
Derived* derived = static_cast<Derived*>(base);
// or
Derived* derived = (Derived*)base;
```

In both cases, the same result is achieved. Though using `static_cast` has the extra benefit of compile-time checking.&#x20;

`reinterpret_cast` and `const_cast` are both last resort measures that should never be used in the first place.&#x20;

`dynamic_cast` is admittedly useful, but leads to poor program design, and has a large overhead each time it is invoked. It is generally avoidable in modern C++ applications.&#x20;

Therefore, C++ casting operators are not so much better than C-style casting. Casting in general should be avoided; but when it is used, understand what happens behind the scenes.&#x20;
