Difference between revisions of "Intermediate C++ Game Programming Tutorial 22"
From Chilipedia
(→Video Timestamp Index) |
(→Video Timestamp Index) |
||
(31 intermediate revisions by the same user not shown) | |||
Line 59: | Line 59: | ||
<div class="mw-collapsible-content"> | <div class="mw-collapsible-content"> | ||
** If you throw an exception, the code is going to jump out of the current function to wherever it is being caught | ** If you throw an exception, the code is going to jump out of the current function to wherever it is being caught | ||
− | ** Upon jumping out of scope, all objects in scope will be | + | ** Upon jumping out of scope, the destructors of all objects in scope will be called. This is called "unwinding the stack" |
** However, any objects created on the heap will not be destroyed, resulting in a memory leak | ** However, any objects created on the heap will not be destroyed, resulting in a memory leak | ||
** This is avoided by using unique (smart) pointers and allocate memory with <code>std::make_unique<>()</code> instead of using raw pointers and <code>new</code> | ** This is avoided by using unique (smart) pointers and allocate memory with <code>std::make_unique<>()</code> instead of using raw pointers and <code>new</code> | ||
Line 66: | Line 66: | ||
* Exceptions and destructors [https://youtu.be/DMdyz0lrFBI?t=17m17s 17:17] | * Exceptions and destructors [https://youtu.be/DMdyz0lrFBI?t=17m17s 17:17] | ||
<div class="mw-collapsible-content"> | <div class="mw-collapsible-content"> | ||
− | ** Never have destructors throw exceptioins, this will mess up execution bigly | + | ** Never have destructors throw exceptioins, this will mess up execution ::bigly:: |
** If you call any functions that can throw exceptions in a destructor, make sure you always catch them | ** If you call any functions that can throw exceptions in a destructor, make sure you always catch them | ||
</div> | </div> | ||
Line 85: | Line 85: | ||
</div> | </div> | ||
[https://youtu.be/_6G5yDgoWiA Tutorial 22 Part 2] | [https://youtu.be/_6G5yDgoWiA Tutorial 22 Part 2] | ||
+ | <div class="mw-collapsible mw-collapsed"><br /> | ||
+ | * Exceptions, applied in practice [[RPG Project Twin]] in the Chili Framework [https://youtu.be/_6G5yDgoWiA?t=0m10s 0:10] | ||
+ | <div class="mw-collapsible-content"> | ||
+ | ** A custom class <code>ChiliException</code> is defined (not recommended, rather inherit from <code>std::exception</code>) that holds message, filename and line number information and virtual functions for information getters defined in derived classes | ||
+ | ** An inner class <code>Graphics::Exception</code> is defined that inherits from <code>ChiliException</code> and adds a data member of type <code>HRESULT></code> (used in DirectX) | ||
+ | ** The Windows API doesn't use exceptions, so individual tests for every function using <code>FAILED</code> calls are used to throw exceptions. Macros such as <code>CHILI_GFX_EXCEPTION()</code> are used to generate the exceptions | ||
+ | ** In <code>Main.cpp</code>, Chili uses a <code>try{ }</code> inside another <code>try{ }</code>. The first is used to test if the creation of a <code>MainWindow</code> object succeeds, the second to throw exceptions using <code>wnd.ShowMessageBox()</code> of that <code>MainWindow</code> class | ||
+ | </div> | ||
+ | * The use of macros to generate exceptions [https://youtu.be/_6G5yDgoWiA?t=4m22s 4:22] | ||
+ | <div class="mw-collapsible-content"> | ||
+ | ** A macro <code>CHILI_GFX_EXCEPTION()</code> is implemented that expands to a constructor for <code>Graphics::Exception()</code>, that also takes two pre-processor defined macros (defined by the compiler): | ||
+ | *:- <code>_CRT_WIDE(__FILE__)</code>, for the filename | ||
+ | *:- <code>__LINE__</code>, for the line number in the code | ||
+ | ** You need to use a macro for this to get the line number of each function call at the different throw points (instead of the line number of the function definition) | ||
+ | </div> | ||
+ | * The use of the <code>HRESULT</code> function [https://youtu.be/_6G5yDgoWiA?t=5m42s 5:42] | ||
+ | <div class="mw-collapsible-content"> | ||
+ | ** <code>>HRESULT hr</code> is used to perform a lookup <code>DXGetErrosString(hr)</code> of the error name string | ||
+ | </div> | ||
+ | * Working with streams (<code>std::ifstream file</code> and exceptions in the <code>Sound</code> class [https://youtu.be/_6G5yDgoWiA?t=7m05s 7:05] | ||
+ | <div class="mw-collapsible-content"> | ||
+ | ** For example: file reading to load sounds | ||
+ | ** Steams don't work with exceptions by default, you have to check the error flags to throw based on that | ||
+ | ** <code>file.exceptions(std::ifstream::failbit | std::ifstream::badbit);</code> turns on the excceptions for the failure and bad flags | ||
+ | </div> | ||
+ | * Recovering from an exception [https://youtu.be/_6G5yDgoWiA?t=9m33s 9:33] | ||
+ | <div class="mw-collapsible-content"> | ||
+ | ** For example: loading resources (like sound). By using a <code>soft_fail</code> flag, an empty sound gets added to the matrix of sounds so that the program can continue. In case of a hard fail the exception gets rethrown and stops the program. | ||
+ | ** Chili uses <code>#ifndef NDEBUG throw e; #endif</code> to always throw when in debug mode | ||
+ | </div> | ||
+ | * Recap of main take-aways [https://youtu.be/_6G5yDgoWiA?t=11m32s 11:32] | ||
+ | <div class="mw-collapsible-content"> | ||
+ | ** DO inherit from <code>std::exception</code> | ||
+ | ** DO use exceptions for errors that happan that are out of programmer's control | ||
+ | ** DO NOT use exceptions for sanity checks (use assert) | ||
+ | ** DO throw by value | ||
+ | ** DO catch by const ref& | ||
+ | ** DO use smart RAII types like smart pointers ALL THE TIME | ||
+ | ** DO NOT throw exceptions from a destructor | ||
+ | ** DO NOT throw exceptions from a move constructor if you want the move optimization in a <code>std::vector</code> etc. | ||
+ | ** DO mark functions as <code>noexcept</code> if you are confident that they will NEVER want to throw an exception, either now, or later on in development | ||
+ | ** DO not mark functions <code>noexcept</code> just because they happen not to throw right now - they might in the future so think carefully before going down the noexcept path | ||
+ | ** DO NOT use exceptions for flow control | ||
+ | </div> | ||
+ | * Homework assignment [https://youtu.be/_6G5yDgoWiA?t=14m06s 14:06] | ||
+ | </div> | ||
== Extra Discussion == | == Extra Discussion == |
Latest revision as of 05:59, 25 November 2019
In this video we learn how to use C++ exceptions to take our error handling to the next level. There is a lot of fear and ignorance surrounding exceptions among "C++ Programmers", and Chili's goal here is to elevate you guys above the shit-tier level to coders who can actually use this feature to its full extent. The second part of this tutorial will give concrete, practical examples of using exceptions in an actual game scenario.
Contents
[hide]Topics Covered
- Basic exception
try
ingthrow
ing andcatch
ing - Exceptions 'bubbling up'
- Rethrowing with
throw
-
catch(...)
-
std::exception
and its derivatives - Polymorphism in exception handling
- Exceptions and destructors
-
noexcept
and move constuctors vs. standard containers - Throw by value, catch by
const
reference
Video Timestamp Index
[Expand]
- Intro: exceptions are the main way of handling errors in C++ 0:10
- Comparing error handling with and without exceptions 1:40
- Example code to demonstrate
try
,throw
,catch
of astd::runtime_error("...")
3:53
- Use
catch(...)
to catch any uncaught excepions 8:55
- Good practice: only throw exception objects that inherit from the
std::exception
class 9:51
-
std::exception
and its derivatives 10:49
- Unwinding the stack: what happens to objects when throwing out of scope 13:39
- Exceptions and destructors 17:17
- Move semantics and containers 18:34
- Best practices 21:56
[Expand]
- Exceptions, applied in practice RPG Project Twin in the Chili Framework 0:10
- The use of macros to generate exceptions 4:22
- The use of the
HRESULT
function 5:42
- Working with streams (
std::ifstream file
and exceptions in theSound
class 7:05
- Recovering from an exception 9:33
- Recap of main take-aways 11:32
- Homework assignment 14:06
Extra Discussion
I had an interesting exchange with a viewer, and made a bit of a writeup here: essay time.