Monday, 8 March 2021

Chapter 19 // Exercise 16 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and a modified version of the std_lib_facilities header found here.

Chapter 19 // Exercise 16

Sometimes, it is desirable that an empty vector be as small as possible. For example, someone might use vector<vector<vector<int>>>  a lot but have most elements vectors empty. Define a vector so that sizeof(vector<int>) == sizeof(int*), that is, so that the vector itself consists only of a pointer to a representation consisting of the elements, the number of elements, and a space pointer.


I was a bit confused at first due to the wording as I thought he meant to have 2 pointers but it could only be the size of 1 pointer. But, after re-reading the question several times realised he meant for the vector representation to hold all three.

I basically reused the vector created in exercises 8 and 9 but took out the allocator and used new and delete instead. This created an entire evening of nightmares. If I didn't understand the difference between copy/move constructors and copy/move assignment before; I sure as hell do now.

I ended up using the crt debug library to track down the exact new that was causing me problems and I realised that my move assignment was not deleting properly. I've left the crt stuff in the code; it's an extremely useful tool.


I also became a pedantic about my vectors. I wanted the original vector to be a fully functional vector in it's own right and the SmallVector to just rely on all of OriginalVector's functions. I think that's what caused me the headache as I tried to separate in my head what was an allocation and what wasn't. 

Ultimately, a frustrating yet extremely rewarding exercise.

When I ran the code a vector<vector<vector<int>>> reported a size of 16 and my SmallVector<SmallVector<SmallVector<int>>> was 4.

And with that, Chapter 19 is finally over. I started it on the 22nd of December and it was beginning to feel like the chapter that would never end. That said I've been doing about 3000 other projects in-between. I really need to focus on this book more.

Sunday, 7 March 2021

Chapter 19 // Exercise 14, 15 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and a modified version of the std_lib_facilities header found here.

Chapter 19 // Exercise 14

Provide a GUI interface and a bit of graphical output to the "Hunt the Wumpus" game from the exercises in Chapter 18. Take the input in an input box and display a map of the part of the cave currently known to the player in a window.

Chapter 19 // Exercise 15

Modify the program from the previous exercise to allow the user to mark rooms based on knowledge and guesses, such as "maybe bats" and "bottomless pit."

Github: 

I was both happy and filled with dread at this exercise as my code had been hackily hard coded to suit a console window environment. I then almost gave up as I realised just how much code relied on _getch() pausing the window. After much drinking, I then remembered state machines are thing and hackily threw together a quick state system that forces the game to wait for presses. I then changed all the couts to a stringstream and pushed that to a new widget called Multiline_Outbox which was created from an Fl_Multiline_Outbox.

For the second part, I quickly added another input box where you can type "13p" or "13b" to mark it with a guess. There is no testing anywhere in this game for incorrect input so, put the right input in.

This is quite possibly some of the worst code I've ever written but I'm glad I didn't skip the exercises. I wanted to make it prettier but I also really want to move onto chapter 20.

Due to the amount of file changes I've uploaded the full project to github as well as the main files.

Chapter 19 // Exercise 14, 15  - Principles & Practice Using C++













Thursday, 4 March 2021

Chapter 19 // Exercise 13 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and a modified version of the std_lib_facilities header found here.

Chapter 19 // Exercise 13

Write a Tracer class where its constructor prints a string and its destructor prints a string. Give the strings as constructor arguments. Use it to see where RAII management objects will do their job (i.e., experiments with Tracers as local objects, member objects, global objects, objects allocated by new, etc.). Then add a copy constructor and a copy assignment so that you can use Tracer objects to see when copying is done.


You won't see the destructor calls for anything except the Tracer allocated by new because the rest are destroyed on return 0.

I did find out how to print line numbers in this exercise though. __LINE__ is a very handy macro. There are several others that you can use to print the file, time etc,.

Tuesday, 2 March 2021

Chapter 19 // Exercise 12 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and a modified version of the std_lib_facilities header found here.

Chapter 19 // Exercise 12

Define a File_handle class with a constructor that takes a string argument (the file name), opens the file in the constructor, and closes it in the destructor.


I'm not sure if he wanted us to use ofstream or ifstream or even the c-style FILE. Or if he wanted us to open a file that already exists or open a new file, or use FILE to guess? I decided to go with the simple option of a file to open that already exists seeing as how FILE has not been introduced.

Monday, 1 March 2021

Chapter 19 // Exercise 11 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and a modified version of the std_lib_facilities header found here.

Chapter 19 // Exercise 11

Design and implement a counted_ptr<T> that is a type that holds a pointer to an object of type T and a pointer to a "use count" (an int) shared by all counted pointers to the same object of type T. The use count should hold the number of counted pointers pointing to a given T

Let the counted_ptr's constructor allocate a T object and use a count on the free store. Let counted_ptr's constructor take an argument to be used as the initial value of the T elements. When the last counted_ptr for a T is destroyed, counted_ptr's destructor should delete the T.

Give the counted_ptr operations that allow us to use it as a pointer. This is an example of a "smart pointer" used to ensure that an object doesn't get destroyed until after its last user has stopped using it. Write a set of test cases for counted_ptr using it as an argument in calls, container elements, etc.


So I think this is basically a shared pointer and it took me a moment to wrap my head around what to do. The main key things are to ensure we're not allocating when copying (or increasing if the pointers are pointing at the same thing) as well as only delete the object and counter once all the other shared pointers have gone out of scope.