This project will help you show your mastery of dynamic arrays, classes, and libraries. (This time it is a dynamic array as a member of a class.)
Somewhere on the net, you find a lovely little class designed to help manage a list of temperature values. You think it could be a decent basis for more general purposes, so you download it and begin your enhancements. Here are the links, in case you forgot to bookmark them (*grin*):
First you'll need to remove all specific references to 'temperature' to make it a generic list of double data. This may require changes to identifiers, strings, etc. in various places.
Next add a method called get_last with no input to return [a copy of] the last item currently in the list. (Note that this will not change the list's contents...)
Now add a method called delete_last. It will remove the last item from the list. It can be a pure void function — no inputs and no output. (But this one, does change the list's contents! In particular, don't forget to update the size member variable...oh, that's how you remove it, isn't it? *silly Jason*)
If get_last is called by an empty list object, you may return 0.0 or NaN. If delete_last is called by an empty list object, you may simply ignore the attempt.
As a final upgrade from the temperature list, you decide you should make the list member variable dynamic instead of 'static'. You'll need to pass the number of items to be in the list to the constructor and an extra member variable to track the size. (I'd rename the current member variable something like physical_size and call this new one logical_size, but any reasonable pair of names will do...)
Remember where nullptr checks should be placed. Don't forget your destructor! (And with that, don't forget your copy constructor and your operator=...)
Place your class in its own library. Make a driver program capable of thoroughly testing its capabilities.
Other libraries may also be used for collections of functions.
This assignment is (Level 3.5).
For all of the next four options, a doubling scheme is strongly recommended for the growth algorithm itself. Toward this end, if the space requested by a programmer outside the class — should you do that option — were not a power of two, you should make it the next higher power of two to keep things exactly doubled.
Add (Level 1.5) to make the list grow when the programmer using the class feels it is necessary. If there are 16 spots which are all full and a new item is waiting to be placed, the programmer can request that you increase the size of the list before they try to place the new item again. You can decide the growth 'algorithm' yourself (i.e. internal to the class so the programmer just says 'grow now' or instead let the programmer decide how much to grow by passing an argument to the growth method that tells how much to increase the list's size). (If allowing the programmer to specify a new size, as noted above, if growth isn't consistent, you can actually cause more fragmentation problems than you solve.)
Add another (Level 1.5) to make the list growth automatic — so that the programmer doesn't have to even think about it. The list knows when they're trying to add more than it can store and grows right away!
Add another (Level 1.5) to make the list shrink as well as grow. So if the programmer has removed items, you can shrink the array to release the wasted elements. (This shrinkage should be either on command or automatic depending on the growth you chose above. It should be per element or per block depending on the growth scheme you chose.)
Add another (Level 1) to make the shrinkage optimistic. Instead of immediately shrinking as soon as there is/are enough empty elements, wait one extra 'half' before shrinking. This allows for the programmer to add more elements without having to experience the speed hit of growing the list again. So, if you've got 8 used elements of 16, don't immediately shrink. Wait until there are 4 used elements and then shrink one step — down by 8. Try to always leave at least one empty space after you shrink so that they have a little room to 're-grow' without allocation woes.
The remaining options are on other aspects to clean up the design and make the resulting class even more reusable.
Add (Level 2.5) to overload operators appropriately for your List class. (Maybe [], +=, >>, <<, etc.) (Note: operator= doesn't count since you needed it for the dynamic memory to begin with!)
Add (Level 4) to make your dynamic array member's type into a template. That's right: make the entire class into a template. Cool, hunh?
Note: This project is adapted from ones given in textbooks by Walter Savitch.