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

From Chilipedia
Jump to: navigation, search
(Created page with "This tutorial is epoch-making, DO NOT SKIP IT. The ostensive main topic for this video is destructors, but that is not where its soul lies. After learning about dtors, we are...")
 
(Homework)
 
(18 intermediate revisions by the same user not shown)
Line 1: Line 1:
This tutorial is epoch-making, DO NOT SKIP IT. The ostensive main topic for this video is destructors, but that is not where its soul lies. After learning about dtors, we are ready to discuss a matter that is at the heart of C++: RAII. This will form the bridge between low-level memory management, and high level smart objects. We also discuss the important concept of deep copying and the Rule of 3, and related to this, we review the 4 original special member functions. AND there are discussion of a bunch of other random bullshit, like converting construction for example. It's a big video is what I'm tryin' to say here.
+
This tutorial is epoch-making; <span style="color:red">'''DO NOT SKIP IT'''</span>. The ostensive main topic for this video is destructors, but that is not where its soul lies. After learning about dtors, we are ready to discuss a matter that is at the heart of C++: RAII. This will form the bridge between low-level memory management, and high level smart objects. We also discuss the important concept of deep copying and the Rule of 3, and related to this, we review the 4 original special member functions. AND there are discussion of a bunch of other random bullshit, like converting construction for example. It's a big video is what I'm tryin' to say here.
  
 
== Topics Covered ==
 
== Topics Covered ==
Line 13: Line 13:
 
* Deleting Special Member Functions with <code>= delete</code>
 
* Deleting Special Member Functions with <code>= delete</code>
 
* Conditions when Special Members Cannot be Generated by Compiler
 
* Conditions when Special Members Cannot be Generated by Compiler
 
== Notes ==
 
  
  
 
== Video Timestamp Index ==
 
== Video Timestamp Index ==
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Announcing Member Functions]
+
* [https://youtu.be/OwDJGrV3pgM Video Start]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Destructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=2m36s Announcing Member Functions]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s RAII]
+
* [https://youtu.be/OwDJGrV3pgM?t=3m33s Destructors]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Special Member Functions]
+
* [https://youtu.be/OwDJGrV3pgM?t=8m26s RAII]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Default Constructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=10m00s Special Member Functions]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Conditions when Default Ctor not Defined]
+
* [https://youtu.be/OwDJGrV3pgM?t=11m09s Default Constructors]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Conditions when Default Ctor Impossible for Compiler to Generate]
+
* [https://youtu.be/OwDJGrV3pgM?t=12m04s Conditions when Default Ctor not Defined]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Copy Constructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=12m40s Conditions when Default Ctor Impossible for Compiler to Generate]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Copy Assignment Operators]
+
* [https://youtu.be/OwDJGrV3pgM?t=15m10s Copy Constructors]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Conditions when Copy Ctor Impossible for Compiler to Generate]
+
* [https://youtu.be/OwDJGrV3pgM?t=18m51s Copy Assignment Operators]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Destructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=19m41s Conditions when Copy Ctor Impossible for Compiler to Generate]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Destructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=23m26s Copy Constructing with <code>=</code>]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Destructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=24m57s Converting Constructors]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Destructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=26m13s <code>explicit</code> Constructors]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Destructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=27m08s Calling Constructors with <code>()</code> vs. <code>{}</code>]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Destructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=28m38s Example of a Class that Manages a Resource]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Destructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=30m16s Problem with Using Compiler-Generated Copy Ctor (Shallow Copy Problem)]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Destructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=34m52s Deep Copy Constructor]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Destructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=38m52s Problem with Using Compiler-Generated Copy Assign (Shallow Copy Problem)]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Destructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=40m02s Deep Copy Assign]
* [https://youtu.be/OwDJGrV3pgM?t=16m25s Destructors]
+
* [https://youtu.be/OwDJGrV3pgM?t=42m08s Rule of 3]
 +
* [https://youtu.be/OwDJGrV3pgM?t=43m27s Rule of 0]
 +
* [https://youtu.be/OwDJGrV3pgM?t=44m29s Calling Copy Assign from Copy Ctor]
 +
* [https://youtu.be/OwDJGrV3pgM?t=45m36s Explicitly Deleting Special Functions]
 +
* [https://youtu.be/OwDJGrV3pgM?t=47m15s Homework]
  
 
== Source Code ==
 
== Source Code ==
[https://github.com/planetchili/intlo GitHub Repo for tutorial]<br />
+
[https://github.com/planetchili/Memesweeper GitHub Repo for Memesweeper]<br />
[https://github.com/planetchili/Memesweeper GitHub Repo for homework (Memesweeper)]
+
[https://github.com/planetchili/intlo GitHub Repo for Tutorial 6]<br />
 
+
[https://github.com/planetchili/LinkedListStack GitHub Repo for Homework (Stack)]
== Downloads ==
+
[http://www.gutenberg.org/files/2600/2600-0.txt War and Peace]<br />
+
[http://www.gutenberg.org/ebooks/5348.txt.utf-8 Ragged Dick]
+
  
 
== Homework ==
 
== Homework ==
Modify Memesweeper so that the array for the field is dynamically allocated depending on play field selection by the user at the beginning of the game. After a game over, the game should be able to return to the menu so that the user can play again without restarting the application.
+
The homework is to create a stack container that is implemented with with a linked list data structure. The skeleton of the interface for the Stack class is given in the source code (see the Downloads above). These are the minimum functions that must be implemented. For further information on stacks, see [https://youtu.be/Cjx5C2I3UrA?t=9m53s this video]. For further information on linked lists, see [https://youtu.be/j1ZF__Ml5ds?t=20m10s this video]. Furthermore, additional research is highly recommended.
 +
 
 +
The behaviors of the interface functions are for the student to infer, with the exception of the Pop() function. In the case of calling Pop() on an empty stack, the function shall return -1. The internal implementation details are also to be determined by the student, but they must at their core use a linked list data structure.
 +
 
 +
When the Stack is fully implemented and the program is executed, there are 8 test routines that will be run. All test routines should output 'Passed' to the console for the homework to be considered solved. Furthermore, the heap memory will be monitored at the end of the program and any dynamic memory that has not been freed will trigger a diagnostic error message. It is required that no diagnostic error be output for the homework to be considered solved.
 +
 
 +
The string routines developed during Intermediate are available for use (but are not strictly necessary). The student may not modify any of the test code. The student may not use any additional classes/functions from the standard library or any 3rd party library. If necessary, it is recommended that the Stack class be developed in a separate solution and tested with custom testing code and diagnostic outputs. Then when the Stack class is deemed ready, it can be transplanted into the test solution for final validation.
  
A menu system and UI has already been implemented for you, all you need to do is figure out how to handle the output from the menu, and then modify the game engine to use dynamic allocation and to reset the field after every game.
+
Solution video available here: [https://www.youtube.com/watch?v=lxAzSRxxrH0 homework solution]
  
 +
== Errata ==
 +
* <span style="color:red">'''It is very important'''</span> to check for '''self assignment'''. If the user of your class tries to do <code>myObj = myObj;</code>, and you do not detect this case, what your code will do is allocate new memory, set myObj's internal pointer to that memory (leaking it), and then it will delete the new memory, giving you an invalid pointer. Actual cancer. Chili neglected to do a check for this case in his examples or in the homework solution, and for this he is surely going to Hell.
 +
* The destructor of <code>DynamicIntArray</code> frees the dynamic memory block with <code>delete pArray</code>, but since it was allocated with <code>new int[]</code> it should have been freed with <code>delete [] pArray</code>.
 +
* The text at 39:38 got messed up and goes off of the screen partially. It should have read: "Remember, before assignment the object being assigned to already owned some memory, and when we overwrite the pointer we lose track of that memory forever."
 +
* In <code>Stack::Element</code>, we implement the destructor and the copy constructor, but not the copy assignment. This violates the Rule of 3, and if someone later accidentally uses the copy assignment operator (fairly possible), they're gonna get their shit fucked up. Since we don't need it, it would be best just to delete it with <code>= delete</code>.
  
 
== See also ==
 
== See also ==
 
* [[Intermediate C++ Game Programming Tutorial 7|Next in series (Tutorial 7)]]
 
* [[Intermediate C++ Game Programming Tutorial 7|Next in series (Tutorial 7)]]
 
* [[Intermediate C++ Game Programming Series]]
 
* [[Intermediate C++ Game Programming Series]]

Latest revision as of 21:29, 27 April 2020

This tutorial is epoch-making; DO NOT SKIP IT. The ostensive main topic for this video is destructors, but that is not where its soul lies. After learning about dtors, we are ready to discuss a matter that is at the heart of C++: RAII. This will form the bridge between low-level memory management, and high level smart objects. We also discuss the important concept of deep copying and the Rule of 3, and related to this, we review the 4 original special member functions. AND there are discussion of a bunch of other random bullshit, like converting construction for example. It's a big video is what I'm tryin' to say here.

Topics Covered

  • RAII (Resource Allocation Is Initialization)
  • Deep Copy vs. Shallow Copy
  • Rule of 3 / Rule of 0
  • Destructors
  • Special Member Functions
  • Converting Constructors
  • explicit Keyword for Constructors
  • Copy Construction with Assignment operator =
  • Constructing with () vs. with {}
  • Deleting Special Member Functions with = delete
  • Conditions when Special Members Cannot be Generated by Compiler


Video Timestamp Index

Source Code

GitHub Repo for Memesweeper
GitHub Repo for Tutorial 6
GitHub Repo for Homework (Stack)

Homework

The homework is to create a stack container that is implemented with with a linked list data structure. The skeleton of the interface for the Stack class is given in the source code (see the Downloads above). These are the minimum functions that must be implemented. For further information on stacks, see this video. For further information on linked lists, see this video. Furthermore, additional research is highly recommended.

The behaviors of the interface functions are for the student to infer, with the exception of the Pop() function. In the case of calling Pop() on an empty stack, the function shall return -1. The internal implementation details are also to be determined by the student, but they must at their core use a linked list data structure.

When the Stack is fully implemented and the program is executed, there are 8 test routines that will be run. All test routines should output 'Passed' to the console for the homework to be considered solved. Furthermore, the heap memory will be monitored at the end of the program and any dynamic memory that has not been freed will trigger a diagnostic error message. It is required that no diagnostic error be output for the homework to be considered solved.

The string routines developed during Intermediate are available for use (but are not strictly necessary). The student may not modify any of the test code. The student may not use any additional classes/functions from the standard library or any 3rd party library. If necessary, it is recommended that the Stack class be developed in a separate solution and tested with custom testing code and diagnostic outputs. Then when the Stack class is deemed ready, it can be transplanted into the test solution for final validation.

Solution video available here: homework solution

Errata

  • It is very important to check for self assignment. If the user of your class tries to do myObj = myObj;, and you do not detect this case, what your code will do is allocate new memory, set myObj's internal pointer to that memory (leaking it), and then it will delete the new memory, giving you an invalid pointer. Actual cancer. Chili neglected to do a check for this case in his examples or in the homework solution, and for this he is surely going to Hell.
  • The destructor of DynamicIntArray frees the dynamic memory block with delete pArray, but since it was allocated with new int[] it should have been freed with delete [] pArray.
  • The text at 39:38 got messed up and goes off of the screen partially. It should have read: "Remember, before assignment the object being assigned to already owned some memory, and when we overwrite the pointer we lose track of that memory forever."
  • In Stack::Element, we implement the destructor and the copy constructor, but not the copy assignment. This violates the Rule of 3, and if someone later accidentally uses the copy assignment operator (fairly possible), they're gonna get their shit fucked up. Since we don't need it, it would be best just to delete it with = delete.

See also