10 – Iterators C++ Templates 4.6 The Iterator pgs

Slides:



Advertisements
Similar presentations
Review of C++ Programming Part II Sheng-Fang Huang.
Advertisements

STL Standard Template Library ● Good reference book: – The C++ Standard Library ● A Tutorial and Reference ● by Nicolai M. Josuttis ● 1999 – Addison Wesley.
1 Today’s Objectives  Announcements Turn in Homework #1 Homework #2 is posted and it is due on 21-Jun  Review Quiz #1  Pointers and C-style strings.
Comp 245 Data Structures Linked Lists. An Array Based List Usually is statically allocated; may not use memory efficiently Direct access to data; faster.
CS Midterm Study Guide Fall General topics Definitions and rules Technical names of things Syntax of C++ constructs Meaning of C++ constructs.
CSE 232: C++ memory management Overview of Arrays Arrays are the simplest kind of data structure –One item right after another in memory (“contiguous range”
Computer Organization and Design Pointers, Arrays and Strings in C Montek Singh Sep 18, 2015 Lab 5 supplement.
Why Use Namespaces? Classes encapsulate behavior (methods) and state (member data) behind an interface Structs are similar, but with state accessible Classes.
Prof. amr Goneid, AUC1 CSCE 110 PROGRAMMING FUNDAMENTALS WITH C++ Prof. Amr Goneid AUC Part 15. Dictionaries (1): A Key Table Class.
CSE 332: C++ template examples Today: Using Class and Function Templates Two examples –Function template for printing different types –Class template for.
CSE 332: C++ pointers, arrays, and references Overview of Pointers and References Often need to refer to another object –Without making a copy of the object.
Motivation for Generic Programming in C++
Examples (D. Schmidt et al)
CS212: Object Oriented Analysis and Design
“Generic Programming” ECE 297
Pointers and Dynamic Arrays
Computer Organization and Design Pointers, Arrays and Strings in C
Andy Wang Object Oriented Programming in C++ COP 3330
C++ Templates.
Lecture 7-2 : STL Iterators
Motivation and Overview
Exceptions, Templates, and the Standard Template Library (STL)
CSCE 210 Data Structures and Algorithms
Dr. Bernard Chen Ph.D. University of Central Arkansas
Sorting Algorithms.
Multi-dimensional Array
C++ History C++ was designed at AT&T Bell Labs by Bjarne Stroustrup in the early 80's Based on the ‘C’ programming language C++ language standardised in.
Generic Programming Techniques in C++
Monday, March 19, 2018 Announcements… For Today… For Next Time…
Starting Out with C++ Early Objects Eighth Edition
The dirty secrets of objects
Tuesday, February 20, 2018 Announcements… For Today… 4+ For Next Time…
The C++ Algorithm Libraries
Collections Intro What is the STL? Templates, collections, & iterators
8.1 Tree Terminology and Applications
Lab 08 - BST.
Prof. Michael Neary Lecture 7: The STL Prof. Michael Neary
Lab 10 - Quicksort.
C++ Templates L03 - Iterator 10 – Iterator.
2.5 Reasoning about Programs: Assertions and Loop Invariants
Lecture 7-2 : STL Iterators
Lab 04 – Linked List.
Wednesday, April 11, 2018 Announcements… For Today…
Today’s Learning Objective
3.3 Abstract Classes, Assignment, and Casting in a Hierarchy
Lab 03 - Iterator.
15 – Sequential Containers
Chapter 3 Lists, Stacks, and Queues Abstract Data Types, Vectors
More About Data Types & Functions
14 – Sequential Containers
priority_queue<T>
Chapter 9 One-Dimensional Arrays
Andy Wang Object Oriented Programming in C++ COP 3330
Why Use Namespaces? Classes encapsulate behavior (methods) and state (member data) behind an interface Structs are similar, but with state accessible Classes.
The Standard Template Library
Engineering Problem Solving with C++, Etter
Lecture 8 : Intro. to STL (Standard Template Library)
Standard Template Library (STL)
C++ Templates L03 - Iterator 10 – Iterator.
Lecture 8-2 : STL Iterators and Algorithms
C++ Templates L03 - Iterator 10 – Iterator.
Arrays Arrays A few types Structures of related data items
Standard Template Library
Collections Intro What is the STL? Templates, collections, & iterators
An Introduction to STL.
Lab 03 – Linked List.
16 – Sequential Containers
Lab 04 - Iterator.
C++ Templates L04 - Iterator 10 – Iterator.
Data Structures & Programming
Presentation transcript:

10 – Iterators C++ Templates 4.6 The Iterator pgs. 264-271 Lab 03 - Iterator Strings Are Really Templates Refactoring Friends 10 – Iterators

Tip #10: Strings vs Character Arrays Iterators Character arrays Size allocated statically. More memory cannot be allocated at run time. Unused allocated memory is wasted. Strings Size allocated dynamically. Memory allocated at run time on demand. Memory is pre-allocated, no memory is wasted. Threat of array decay (loss of type and dimensions when passing an array into function by value or pointer). As strings are represented as objects, no array decay occurs. String class functions: Input functions (3), Capacity functions (3), Iterator functions (4), Manipulating functions (2) No inbuilt functions to manipulate strings. (string.h library w/strcpy, strcat, strlen, strcmp, …) Implementations are fast. Implementation are non- standard and SLOW.

Lab 03 - Iterator

Array Container Access Iterators By Index #include <iostream> using namespace std; int main() { int dog[] = { 1, 2, 3, 4 }; int* dptr = dog; for (size_t i = 0; i < 4; ++i) cout << *dptr++ << endl; } return 0; By Pointer #include <iostream> using namespace std; int main() { int dog[] = { 1, 2, 3, 4 }; for (size_t i = 0; i < 4; ++i) cout << dog[i] << endl; } return 0;

 The "Old" Approach #include <iostream> #include <vector> Iterators #include <iostream> #include <vector> using namespace std; int main() { vector<int> myArray; myArray.push_back(1); myArray.push_back(2); myArray.push_back(3); myArray.push_back(4); size_t y = 0; while (y != myArray.size()) cout << myArray[y] << " "; ++y; } return 0; #include <iostream> #include <list> using namespace std; int main() { list<int> myArray; myArray.push_back(1); myArray.push_back(2); myArray.push_back(3); myArray.push_back(4); size_t y = 0; while (y != myArray.size()) cout << myArray[y] << " "; ++y; } return 0; 

The STL Iterator Approach Iterators #include <iostream> #include <vector> using namespace std; int main() { vector<int> myArray; myArray.push_back(1); myArray.push_back(2); myArray.push_back(3); myArray.push_back(4); vector<int>::iterator iter = myArray.begin(); while (iter != myArray.end()) cout << *iter << " "; ++iter; } return 0; #include <iostream> #include <list> using namespace std; int main() { list<int> myArray; myArray.push_back(1); myArray.push_back(2); myArray.push_back(3); myArray.push_back(4); list<int>::iterator iter = myArray.begin(); while (iter != myArray.end()) cout << *iter << " "; ++iter; } return 0;

Why Use an Iterator? When avoiding iterators: Assumes your container has index ([]), at, and increment (++,--)operators. Assumes container elements can be randomly accessed, are contiguous, and same size (true for vector but not for many other containers.) Requires many versions of common algorithms (ie., sort, reverse, etc.) Iterators bring you closer to container independence. You're not making assumptions about random-access ability, storage format, or efficiency of operations such as size(). You only need to know that the container has iterator capabilities. Iterators enhance your code further with standard algorithms. Depending on what it is you're trying to achieve, you may elect to use std::for_each(), std::transform(), std::sort() and so on. By using a standard algorithm rather than an explicit loop you're avoiding re-inventing the wheel. Your code is likely to be more efficient (given the right algorithm is chosen), correct and reusable.

Iterator Lab Iterators The concept of an iterator is fundamental to understanding the C++ Standard Template Library (STL). Iterators provide access to data stored in container classes (e.g. vector, map, list, etc.) Your Iterator lab implements a C++ array container class that uses an iterator to access the array elements. Your container supplies begin() and end() functions. Your iterator object overloads the not equal ("!="), dereference ("*"), and pre-increment ("++") operators. Use an iterator to sequentially access elements of the associated array class. Read integer values from a file into the array class. Instantiate an iterator using the begin() function and then use the iterator to iterate thru the array values until the iterator equals the iterator returned by the end() function.

Nested Class MyArray Iterator Iterators template<typename T> { private: // MyArray data public: MyArray(const size_t maxSize) { ... } void push_back(T item) { ... } std::string toString() const { ... } friend std::ostream& operator<< (std::ostream& os, const MyArray<T>& myArray) {}; }; MyArray Iterator class Iterator { private: // Iterator data and private functions public: Iterator(T* array, size_t size, size_t index) { ... } bool operator!= (const Iterator& other) const { ... } // not-equal Iterator& operator++ () { ... } // pre-increment ++ T& operator*() const { ... } // dereference std::string toString() const { ... } friend std::ostream& operator<< (std::ostream& os, const Iterator& iter) {} }; Iterator begin() { ... } // pointer to first element Iterator end() { ... } // pointer AFTER last element

main Open I/O Streams Read / push_back integer into numbers container. Iterators int main(int argc, char * argv[]) { VS_MEM_CHECK; MyArray<int> numbers(MAX_ARRAY_SIZE); ifstream in(argv[1]); std::ostream& out = (argc < 3) ? std::cout : *(new std::ofstream(argv[2]); out << endl << endl; int i; while (in >> i) numbers.push_back(i); out << numbers << endl << endl; out << "SEQUENTIAL" << endl; MyArray<int>::Iterator iter = numbers.begin(); out << "iter: " << iter << endl; for (; iter != numbers.end(); ++iter) out << *iter << " "; return 0; } Open I/O Streams Read / push_back integer into numbers container. Instantiate Iterator Use friend insertion operator to examine Iterator Output number's contents using dereferencing operator Loop until iter and numbers.end() are equal

Output of Iterator Lab myArray 1 2 3 4 5 6 7 8 9 10 Iterators myArray 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 SEQUENTIAL iter1: size=20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 PRIME (Bonus) 2 3 5 7 11 13 17 19 COMPOSITE (Bonus) 1 4 6 8 9 10 12 14 15 16 18 20 FIBONACCI (Bonus) iter2: size=20 3=1+2

You may freely use the code in any way you deem useful. ****Disclaimer**** The following code examples are flawed and incomplete, but demonstrate how an iterator class might be implemented. You may freely use the code in any way you deem useful.

Step 1 – int Array Class Iterators #include <iostream> #include <string> #include <sstream> #define MAX_ARRAY_SIZE 1000 using namespace std; class MyArray { private: size_t size_; int* array_; public: MyArray(size_t maxSize) : size_(0) { array_ = (int*)malloc(maxSize * sizeof(int)); } void push_back(int item) { array_[size_++] = item; } }; int main(int argc, char * argv[]) { MyArray numbers(MAX_ARRAY_SIZE); numbers.push_back(1); numbers.push_back(2); numbers.push_back(3); numbers.push_back(4); cout << numbers << endl; return 0; } Be sure to use a destructor to free array! string toString() const { stringstream out; out << "myArray"; for (size_t i = 0; i < size_; ++i) out << ((i % 10) ? " " : "\n") << array_[i]; return out.str(); } friend std::ostream& operator<< (ostream& os, const MyArray<T>& myArray) os << myArray.toString(); return os; Remember, every class needs a toString and a Friend!

Step 2 – Template Class Iterators #include <iostream> #include <string> #include <sstream> #define MAX_ARRAY_SIZE 1000 using namespace std; template<typename T> class MyArray { private: size_t size_; T* array_; public: MyArray(size_t maxSize) : size_(0) { array_ = (T*)malloc(maxSize * sizeof(T)); } void push_back(T item) { array_[size_++] = item; } }; int main(int argc, char * argv[]) { MyArray<int> numbers(MAX_ARRAY_SIZE); numbers.push_back(1); numbers.push_back(2); numbers.push_back(3); numbers.push_back(4); cout << numbers << endl; return 0; } Templates are a feature of the C++ programming language that allows functions and classes to operate with generic types, allowing a function or class to work on many different data types without being rewritten for each one. There are three kinds of templates: function templates, class templates and, since C++14, variable templates.

Step 3 – Add a Nested Iterator Iterators #include <iostream> #include <string> #include <sstream> #define MAX_ARRAY_SIZE 1000 using namespace std; template<typename T> class MyArray { private: size_t size_; T* array_; public: MyArray(size_t maxSize) : size_(0) { array_ = (T*)malloc(maxSize * sizeof(T)); } void push_back(T item) { array_[size_++] = item; } class Iterator size_t index_; Iterator(T* a, size_t s) : array_(a), index_(s) { ... } T& operator[](size_t i) const { return array_[i]; } }; Iterator begin() { return MyArray<T>::Iterator(array_, 0); } Iterator end() { return MyArray<T>::Iterator(array_, size_); } int main(int argc, char * argv[]) { MyArray<int> numbers(MAX_ARRAY_SIZE); numbers.push_back(1); numbers.push_back(2); numbers.push_back(3); numbers.push_back(4); MyArray<int>::Iterator iter = numbers.begin(); for (size_t i = 0; i < 4; ++i) cout << iter[i] << ' '; cout << endl << endl; return 0; } MyArray Iterator Nested classes can access all members of the parent via a reference/pointer.

Step 4 – Add Functionality Iterators #include <iostream> #include <string> #include <sstream> #define MAX_ARRAY_SIZE 1000 using namespace std; template<typename T> class MyArray { private: size_t size_; T* array_; public: MyArray(size_t maxSize) : size_(0) { array_ = (T*)malloc(maxSize * sizeof(T)); } void push_back(T item) { array_[size_++] = item; } class Iterator size_t index_; Iterator(T* a, size_t s) : array_(a), index_(s) { ... } T& operator[](size_t i) const { return array_[index_]; } T& operator*() const { ... } Iterator& operator++() { ... } }; Iterator begin() { return MyArray<T>::Iterator(array_, 0); } Iterator end() { return MyArray<T>::Iterator(array_, size_); } int main(int argc, char * argv[]) { MyArray<int> numbers(MAX_ARRAY_SIZE); numbers.push_back(1); numbers.push_back(2); numbers.push_back(3); numbers.push_back(4); MyArray<int>::Iterator iter = numbers.begin(); for (size_t i = 0; i < 4; ++i, ++iter) cout << *iter << ' ‘; cout << endl << endl; return 0; } Add dereference (*) and pre-increment (++) operators.

Requirements Iterators Points Requirement (35 + 10 Points) 5 argv[1] and argv[2] used for input / output streams respectively. No execution user interaction (i.e. system("pause"); or getchr();). A template array class contains unsorted integer numbers. Numbers are added to the container using a push_back member function. The array class contains a nested iterator class. The array class member functions begin() and end() instantiate and return iterator objects; the begin iterator points to the 1st element and the end iterator points after the last element. The iterator class correctly overloads the dereferencing ("*"), pre-incrementing ("++"), and not equal ("!=") function operators. All classes (including the iterator) have public toString and friend insertion member functions. The insertion operator function is used to send the contents of the array container and iterators to the output stream. The array class content from all input files is correctly output using an iterator. BONUS: Add a size() function and index function operator ("[]") to your array class. Use these functions to output the prime and composite array class elements. BONUS: Add a post-increment function operator ("++") to your nested iterator class. Use the dereference and post-increment operators (indirect auto-increment *iter++) to output all Fibonacci-like array class elements. VS_MEM_CHECK macro is included in main to detect memory leaks. No Memory leaks are reported.