Iterators - The Journey So Far
Thomas J. Kennedy
1 Beginning the Journey
We started the semester with a review of the basics from CS 150 and CS 250 (i.e., everything up to Linked Lists). Review 01 started with:
-
Example 1 was an implementation of Linked Lists similar to what one would see at the end of CS 250.
- I briefly reviewed command line arguments during this example.
- The Linked List destructor was introduced in this example.
-
Example 2 was a similar implementation, but with the Node
struct
moved within the scope of the Inventory class.
The next two examples brought in a few best practices (with particular emphasis on the Big-3 and the Copy-and-Swap Idiom):
-
Example 3 included a discussion of the Big-3.
-
Example 4 covered the Copy-and-Swap Idiom.
- I started with a brief review of how to explore an unfamiliar code.
- I discussed the
-fsanitize
compilation flag and using the compiler to detect memory leaks.
The last two examples (i.e., Example 5 and Example 6) were the jump-ahead-a-few-weeks examples (i.e., they were a preview of where we would be at the end of Review 3 and Assignment 2).
2 Iterators in the Wild
Review 02 & Module 3 (working with Iterators) were the beginning of the CS 330 level material (i.e., the first round of entirely new material). Review 02 focused on iterators.
In CS 150 and CS 250 when we needed to iterate over a collection of data, we needed to write data structure specific code. We want to be able to write generic loops (i.e., loops that can be written once, with the details wrapped up in a convenient package). Iterators provide this package.
2.1 Borrowing Existing Iterators
Review 02 started with the basics of Iterators:
-
Example 1 - Use
std::list
’s iterators within House Member functions. -
Example 2 - Use
std::vector
’s iterators with House member functions. -
Example 3 - Allow those iterators to be used outside of House.
- This required a couple
typedef
s. - This required begin and end functions be added to House to expose iterators to the outside world (e.g.,
main
).
- This required a couple
Examples 4 and 5 cleaned up a few things. This was mainly to play with range based for loops.
2.2 Faking Iterators.. With Pointers
Example 6 is where we had to start providing our own iterators.
-
Example 6 - Use a statically allocated array (and the array-resize logic from CS 250) to store the Rooms. Instead of working with the array directly, we want to keep using this Iterator interface (e.g., iterator while loops and range-based for loops).
-
Example 7 - Use a dynamically allocated array (and the array-resize logic from CS 250) to store the Rooms.
At the end of the day pointers and iterators are essentially the same interface, conceptually.
-
Iterators can be compared to one another (e.g., using
==
). Pointers can be compared to one another. -
Iterators can incremented (e.g.,
it++
). Pointers can be incremented (e.g.,p++
). -
Iterators can be dereferenced (e.g.,
*it
). Pointers can be de referenced (e.g.,*p
).
Iterators and pointers have near-identical syntax. The difference is the type of memory:
- Pointers work directly in memory (i.e., raw memory).
- Iterators work with data structure storage (i.e., the data within a data structure).
2.3 Running Out of Luck
Example 8 is where our luck ran out. Linked Lists required us to implement iterators from the ground up (i.e., write wrappers around the Linked List operations used in Review 01 and Assignment 1).
Every time we work with a data structure we end up with a combination of four operations:
- Initialization
- End of Collection Check
- Dereferece
- Increment
Interface | Initialization | End Of Collection Check | Dereference | Increment |
---|---|---|---|---|
Array | int i = 0 |
i < size |
someArray[i] |
i++ |
Linked List | Node* it = head |
it != nullptr |
it->data |
it = it->next |
Iterator | Iterator it = something.begin() |
it != something.end() |
*it |
it++ |
Iterators allow us to define a common interface and hide away the details.
3 Iterators AND The Big-3
Review 03 combined Review 01 (Big-3) and Review 02 (Iterators).
-
Example 1 and Example 2 combine these discussion for Arrays and Linked Lists (i.e.., cover iterators, memory leaks, and the Big-3).
-
Example 3 is where we started to play with the C++
std
functions for iterators (e.g.,std::transform
, andstd::minmax_element
).
4 Moving from Assignment 1 to Assignment 2
If you understand the mechanics from Review 02 (i.e., how to use iterators), you have everything you need to complete Assignment 2.
The key difference between Assignment 1 and Assignment 2 is level of abstraction. In Assignment 1 you implemented the Linked List logic as part of the assignment. All other functions worked directly with the Linked List.
In Assignment 2, you need to rewrite those Linked List specific loops. Instead of working Node pointers (i.e., Node*
), you are now working with Iterators (i.e., one level of abstraction above Assignment 1).
4.1 Cool Iterator Tricks
Review 03 Examples 4 through 6 covered a few fun mechanics we will use discuss again later. However, you are not required to use the fancy std
functions (e.g., std::transform
) to complete Assignment 2.
5 TL;DR
TL;DR - Iterators are our current Abstraction case study. They are new. This is the first time you are working with them.
-
Reading examples and watching recordings gives us a baseline understanding.
-
You will not truly understand iterators until you have worked with them (i.e., written code that uses them) a few times.