Wednesday, 15 September 2021

Chapter 20 // Exercise 17 - Principles & Practice Using C++

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

Chapter 20 // Exercise 17

Define an ownership_vector that holds pointers to objects like pvector but provides a mechanism for the user to decide which objects are owned by the vector (i.e., which objects are deleted by the destructor). Hint: This exercise is simple if you were awake for Chapter 13.


I had to go back and refresh my memory on what Chapter 13 was. It was one of the graphics chapters and I immediately remembered vector_ref. Here Bjarne uses two vectors as member variables. They both hold pointers to objects but one deletes objects when destroyed. Vector_ref is introduced on page 465 in section 13.10. There is also more information in Appendix E on page 1212.

For this I removed some constructors that didn't make sense and when I thought about it, most methods in std::vector didn't really fit having two vectors as members so I deleted them.


Tuesday, 14 September 2021

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

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

Chapter 20 // Exercise 16

Define an ovector that is like a pvector except that [] and * operators return a reference to the object pointed to by an element rather than the pointer.


Due to how I'd implemented the PVector this was quite tricky. I ended up discovering std::remove_pointer<Type>::type in the std library which handily removes pointers from pointer types. So this allows the templated type to still only allow pointer types but when accessing via [] it decays the type and allows it to return a reference to the contents of the pointer whilst still being templated.

For operator * I just returned *vector[0] as I believe de-reffing a vector decays to the first element?

Monday, 13 September 2021

Chapter 20 // Exercise 15 - Principles & Practice Using C++

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

Chapter 20 // Exercise 15

Define a pvector to be like a vector of pointers except that it contains pointers to objects and its destructor deletes each object.


I found the wording on this one really confusing. Like does he mean a vector of pointers to anything (like vector<void*>) or like a vector<int*> where each object is just a standard type. I understand what he's getting us to do though because a vector doesn't call the destructor for a plain pointer. So whereas string will clean itself up when it goes out of scope, a pointer to a string won't call strings destructor when it goes out of scope (because raw pointers don't have destructors) and then a memory leak is created.

At first I tried to inherit from std::vector and add a new destructor but I have no idea what a _Compressed_pair<_Alty, _Scary_val> _MyPair is and just calling delete[] _MyPair wouldn't compile so I gave up as it was completely beyond me. Also I learnt that std::vectors destructor is not virtual so I can't modify it anyway. Google says it's best to not inherit from std::vector unless absolutely necessary.

I ended up creating a class that has a std::vector as a member variable and implementing most std::vector methods with the destructor explicitly calling delete on each pointer element. Using my best friend _CrtDumpMemoryLeaks() at the end of main shows how PVector cleans up after itself and a std::vector leaks memory:



I then added a static_assert to the class to prevent it from compiling if the type given is not a pointer.

Sunday, 12 September 2021

Chapter 20 // Exercise 14 - Principles & Practice Using C++

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

Chapter 20 // Exercise 14

Define a singly-linked list, slist, in the style of std::list. Which operations from list could you reasonably eliminate from slist because it doesn't have back pointers?


So here is the documentation for std::list:

And here is the documentation for a std::forward_list:

A list is usually implemented as a doubly linked list whereas the forward_list is a singly linked list. As Slist can only go forwards, the back() function can be removed. There also can't be any functions that place elements at the back of the list.

I decided to use the definition given for forward_list and try and implement that (minus the allocator and various constructors). I ended up leaving out merge and remove but added functions like swap(), resize(), clear() and maxSize().

Saturday, 11 September 2021

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

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

Chapter 20 // Exercise 13

We don't really need a "real" one-past-the-end Link for a list. Modify your solution to the previous exercise to use 0 to represent a pointer to the (non-existent) one-past-the-end Link (list<Elem>::end()); that way, the size of an empty list can be equal to the size of a single pointer.


This made getting the back() element a little trickier. I just started at the head until the next link was nullptr then returned the value. Removing Tail made pushFront a little less complicated though.

At first I cheated and added a get() function to the iterator but I decided to remove it and use only what had been given for the iterator.