Lecture 23

Casting

  • Allows us to bypass the type system - a manual override for type checking

  • Often a source of error

Casting Example in C:

struct Node n; int \*ip = (int\*) &n; 
// cast - forces C to treat a Node* as an int*. 
  • C-style casts should be avoided in C++. If you must cast, use C++ cast.

Four kinds of casting in C++ (raw pointers):

  1. static_cast

  2. reinterpret_cast

  3. const_cast

  4. dynamic_cast

Four kinds of casting in C++ (smart pointers):

  1. static_pointer_cast

  2. reinterpret_pointer_cast

  3. const_pointer_cast

  4. dynamic_pointer_cast

static_cast

  • Converts one type to another

  • relatively safe

    • compiler gives error if cast doesn't make sense, though it won't catch everything

  • If a casted value isn't actually of the desired type, the behaviour is undefined.

  • "sensible casts"

Example 1:

Example 2:

reinterpret_cast

  • Converts one type to another without checking if it is reasonable

  • Unsafe, implementation-specific, "weird" casts (kind of opposite of static_cast)

  • compiler dependent way of casting

  • Similar to static_cast but doesn't check if cast makes sense

Example:

const_cast

  • For converting between const and non-const

  • the only C++ cast that can "cast away const"

  • Can create cascading errors in your program (if you fix cast one const, then the next part of program may have type errors with const)

Example:

dynamic_cast

  • Safely converts one type to another

  • Can use dynamic casting to make decisions based on an object's run-time type information (RTTI)

  • Only works on classes with at least 1 virtual method

  • Works with references

Example:

  • If the cast works (*pb really is a Text or a subclass of Text), pt points at the objects.

  • If the cast fails, pt will be nullptr

dynamic_cast with References

  • Can be used to solve the polymorphic assignment problem

Example with References:

  • If b "points to" a Text, t2 is a reference to the same Text

  • If not...? (No such thing as a null reference)

    • So an exception is raised - bad_cast

How can referencing be used to solve the polymorphic assignment problem?

dynamic_pointer_cast

  • cast shared_ptrs to shared_ptr

Bad Design Example:

  • Code like this is tightly coupled to the Book hierarchy

  • May indicate bad design

Solution:

  1. Use virtual methods

  2. Write a Visitor (if possible)

More Notes on Casting

  • Why can't we just use dynamic_cast for everything if it's safest?

    • it requires more processing power

How Virtual Methods Work

Why is w double the size of v?

  • v:

    • 8 is space for 2 ints

    • 0 space for f()

  • w:

    • has a vptr (explained in following notes)

Note: Compiler turns methods into ordinary functions and stores them separately from objects

Recall:

  • If isHeavy() is virtual, the choice of which version to run is based on the type of the actual object - which the compiler can't known in advance

  • Therefore, isHeavy() must be chosen at runtime. How is this done?

Compiler choosing which method is correct at runtime

  • For each class with virtual methods, the compiler creates a table of function pointers (the vtable)

C objects have an extra pointer (the vptr) that points to C's vtable.

Last updated

Was this helpful?