Difference between revisions of "Intermediate C++ Game Programming Tutorial 19"

From Chilipedia
Jump to: navigation, search
(Video Timestamp Index)
(Video Timestamp Index)
Line 40: Line 40:
 
** c-style cast (int) etc.
 
** c-style cast (int) etc.
 
*** can do all of the above, even if you don't mean to<br />
 
*** can do all of the above, even if you don't mean to<br />
<code>const Base* pBase = &obj;</code> <br />
+
***<code>const Base* pBase = &obj;</code> <br />
...<br />
+
***...<br />
<code>Derived* pDerived = (Derived*)pBase;</code>
+
***<code>Derived* pDerived = (Derived*)pBase;</code>
 
*** casted away the constness by accident!
 
*** casted away the constness by accident!
 
* WORK-IN-PROGRESS
 
* WORK-IN-PROGRESS

Revision as of 04:48, 16 October 2019

In this video Chili teaches us how to figure out what our polymorphic pointers are actually pointing to (aka "type discovery"). Just note that although we can do this, it is generally a weaksauce way to go about things. Virtual functions are 1000% more hype than type discovery bullshit. Oh yeah, we also finally see all the C++ style casts united.

Topics Covered

  • dynamic_cast<T*> and dynamic_cast<T&>
  • const_cast
  • Overview of all C++ style casts
  • RTTI with typeid()
  • The type_info class

Video Timestamp Index

Tutorial 19

  • Using dynamic_cast<new-type>(expression) to determine to what derived type a pointer to a polymorphic base type is actually pointing 0:54
    • A dynamic cast can be used on pointers and on references
    • To cast (from and to) a pointer, use
      if( DerivedClass* ptr_temp = dynamic_cast<DerivedClass*>(ptr_to_baseClassObject) )
      (note 1: if the cast fails, it will return a nullptr of the DerivedClass type)
      (note 2: nullptr is #defined to 0 and thus evaluates to false inside an if statement)
    • To cast (from and to) a reference, you can use
      DerivedClass& val_temp = dynamic_cast<DerivedClass&>(baseClassObject)
      (but that will throw an exception when the cast fails so it cannot be used inside an if statement)
    • A dynamic cast can be a costly operation (depends on the inheritance tree, nature of the cast, compiler)
    • Dynamic cast only works for types that have at least one virtual function (the operation needs information from the vtable)
  • Using static_cast<>() to convert pointers within an inheritance hierarchy 6:20
    • Suppose: you have a polymorphic DerivedClass that has a nonvirtual member function Foo()
    • You have a pointer BaseClass* ptr = new DerivedClass to the polymorphic base class that you know points to the derived class (the "dynamic type")
    • To call the derived class' member function, you can use a static cast to DerivedClass pointer
      static_cast<DerivedClass*>(ptr)->Foo();
    • ... or a static cast to DerivedClass reference
      static_cast<DerivedClass&>(*ptr).Foo();
  • Using const_cast<>() to remove a const from a reference or pointer (yes, you read that right) 7:27
    • Example of a responsible use case: to overload a [member function that reads from/writes to an array] with a [const version of that function that can only read and returns the value as a const reference]
    • You need that overloaded function if you have a const reference to the object and you want to call the member function
    • Example case inside the TileMap class of the Snek game: the body of the overloaded getter function reads
      return const_cast<TileMap*>(this)->_At(pos);
      in which you remove the const from the pointer to the self object
  • Overview of different types of casts 9:30
    • static_cast
      • converts types (int->float etc.)
      • casts pointers/references within an inheritance hierarchy (no checking of the validity of the cast!)
    • dynamic_cast
      • casts pointers/references within an inheritance hierarchy (dynamic check!)
      • requires that the type have at least one virtual function
      • if check fails, nullptr for ptr* cast, throw exception for ref& cast
    • reinterpret_cast
      • reinterpret pointers/references as pointing to some other type (no check, no limit!) (only really safe for char*)
      • reinterpret pointer as an integral value
    • const_cast
      • remove constness
    • c-style cast (int) etc.
      • can do all of the above, even if you don't mean to
      • const Base* pBase = &obj;
      • ...
      • Derived* pDerived = (Derived*)pBase;
      • casted away the constness by accident!
  • WORK-IN-PROGRESS

Source Code

Note that the code for this video is in a different branch called "casting". You will not find it in the master branch.

See also