This test is a 50 minute written exam designed to explore the Standard Template Library random access data structures vector (chapter 8), and list (chapter 9). The test will cover all of chapter 8 but only the usage of lists in chapter 9. There will be both conceptual questions about overall concepts (the forest), and nitty-gritty questions about the C++ and the Standard Template Library (the trees).
Below are a list of what I see are the important concepts. Questions on the test will focus on these concepts, but I will expect that you should be able to illustrate each concept with nitty-gritty C++ examples.
Chapter 8 provided us with an introduction to vector, the first example of a container object of objects of generic type. This is accomplished through our first experience with the C++ template facility.
- We began with the specication of the vector class template. Note exactly how the template paramter T was used throughout the class definition. You are responsible for being able to recreate a template class definition. Recall how I asked you to create the class complex on the last test. You will be given another new class to create, this time using the template mechanism.
Again our three perspective model of classes should be applied carefully here. In the chapter we first looked at a number of examples illustrating vector usage. We did this primarily to better understand the vector class definition (the specification) in order to then better understand how each operation should be implemented. This model of chapter layout is similar to the chapter layout for strings.
- Know how vectors are used, and be prepared to write or understand a simple program using vectors.
- The sieve of Erastosthenes is a straightforward example of using vectors of ints. Note that the primary access operator on vectors is , just as it is in the C++ built-in array type.
- We reimplemented the sieve using iterator access instead of indexed access. Study it. It is one of the examples you can use to get a better handle on the use of iterators.
- We looked at both the selection sort and the merge sort, with the merge sort being our first example of recursive programming. In both the selection sort (swap) and the merge sort (inplace_merge), we used stl generic algorithms.
- Important: Note that algorithms are implicitly instantiated when they are called from algorithm templates. C++ figures out by itself where the algorithm comes from - whether it is a non-template or template algorithm. This has important ramification for generic algorithms. We don't need to know that generic algorithms actually come from algorithm templates. That way, in chapter 2 we can use a generic algorithm without ever knowing that it actually comes from a template. We don't even have to know what templates are.
- The silly sentence generation program is a good example of how vectors dynamically grow and shrink, but only from the back end. This is a consequence of the contiguous storage model of the implementation. Actually, we should view this the other way around. The contiguous storage model can be used because we only need to add and delete storage from the back end!
- We also talked about matrix manipulation of vectors and how 2-dimensional vectors are similar in usage to 2-dimensional C++ built-in arrays.
- We again spent a number of classes discussing the usage of the vector operations:
- We went over each vector operation in detail, paying close attention to the use of vector iterators. To help us understand their use, we looked at a variety of generic algorithms (find, iter_swap, sort, and merge specifically).
- Character access operations were provided to mimic our basic model of array access.
- We then spent a number of classes on the implementation of vectors. This implementation again presented problems similar to those in the string implementation, again primarily focused on how to manage the dynamic storage allocation and deallocation of vector buffers.- We finished the chapter with the implementation of a number of generic algorithms - fill, copy, inplace_merge, and merge. Know them.
- In implementing the operations reserve and resize we again discussed the C++ provided dynamic storage "heap" along with it's operations new and delete. We encapsulated the use of new and delete inside of reserve, and then used this procedure in most of the operations requiring string creation or resizing.
- As with strings, we decided on a vector implementation in which vector storage would be reallocated by the heap whenever a vector was resized larger. The ramifications of this were that there might be extra space lying around inside a vector if it were ever resized smaller.
- Important: Unlike in the string implementation, both the vector size and storage capacity were represented as integer variables (in the string, only the buffer capacity was explicitly represented. This allowed for quick pushing of new vector storage items on the end of the vector. We also saw that adding a vector item on the end of a vector preallocated storage for future pushes.
- Note how we implemented the vector operators, specifically the item access operator [ ].
- Note also how we implemented the vector iterator directly as a pointer. Again, remember the important discussion about how iterators are not pointers, although they could be implemented with pointers. In this case we implemented them with pointers, and the begin and end operators have simple implementations.
You are responsible for list usage, not list implementation. We went over the list abstraction through two extensive examples - the inventory system and the course registration system. Your questions on lists will be limited to answering specific questions regarding sections of code in these two examples.
Important: Note carefully the use of iterators in the context of both of these programs. I definitely will ask you questions about looping algorithms using iterators. There are some especially nice ones in the registration system. Specifically be aware of how to handle the situation where you are removing elements from a list.