diff --git a/const_cast.md b/const_cast.md new file mode 100644 index 0000000..58d14da --- /dev/null +++ b/const_cast.md @@ -0,0 +1,34 @@ +## `const_cast` conversion +`const_cast` is an explicit cast operator that is mainly used to remove (or add) constness from/to a pointer or reference. +This operator can only remove or add the constness to **what a pointer (or reference) points to**, and *never* the constness of the object itself: otherwise, we would break the immutability of the object. + +## Examples +- Remove constness: +```cpp +int main() { + const int i = 0; + const int* const pointer = &i; + int* x = const_cast(pointer); // Remove const from + // what the pointer points to -- valid + *const_cast(pointer) = 2000; // No compile time error, but undefined + // behavior: we cannot mutate the object x points to, because it is originally const! +} +``` +- Add constness: + ```cpp + int main() { + int i = 0; + int* pointer = &i; + *const_cast(pointer) = 5; // Doesn't compile + // since we added a const qualifier: we now cannot mutate this object's value! +} +``` + +## `const_cas`t might be dangerous to use +Unless you have a very good reason to, *you should avoid `const_cast`*. It can easily lead +to undefined behavior and it's very easy to break the constness-related best practices while using it. + +## Also See +[cppreference: const_cast](https://en.cppreference.com/w/cpp/language/const_cast) +[how to use const_cast?](https://stackoverflow.com/questions/19554841/how-to-use-const-cast) +[is const_cast safe?](https://stackoverflow.com/questions/357600/is-const-cast-safe) diff --git a/dynamic_cast.md b/dynamic_cast.md new file mode 100644 index 0000000..21a4c5e --- /dev/null +++ b/dynamic_cast.md @@ -0,0 +1,31 @@ +## `dynamic_cast` conversion +`dynamic_cast` is an explicit cast operator that is often used when working with inheritance hierarchies, to convert pointers +(and references) from the derived class to the base class (upcasting) and the opposite (downcasting). +This operator performs a runtime check to test whether the conversion can be done: it returns a null pointer on failure. +This implies a little overhead when using it. + +## Useful conversions +`dynamic_cast` is mostly used when we need to downcast a base class to its derived class. +It is important to check whether the cast was successful: we can test whether the pointer returned by +`dynamic_cast` is nullptr, and if it is, the conversion failed. +```cpp +int main() { + Base* base = new Derived; + if (Derived* derived = dynamic_cast(base); derived != nullptr) /* Check that the conversion did not fail */ { + derived->foo(); + } + // Note: If base didn't point to a derived object, the if statement would never execute because derived would be null + delete base; +} +``` + +## Notes +You can downcast with `static_cast` too, but no runtime check is performed. +Unless you can prove that the conversion will not fail, use use dymamic_cast in that it's safer and will avoid +unwanted issues. + + +## See Also +- [cppreference: dynamic_cast](https://en.cppreference.com/w/cpp/language/dynamic_cast) +- [how to down_cast correctly](https://stackoverflow.com/questions/52556957/how-to-use-dynamic-cast-to-downcast-correctly) +- [is dynamic_cast considered bad design?](https://stackoverflow.com/questions/48612271/use-case-of-dynamic-cast)