csc 237 - data structures, fall, 2008 monday, september 29, end of week 5, generic functions and...

20
CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C+ +

Upload: holly-horton

Post on 14-Dec-2015

214 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

CSC 237 - Data Structures, Fall, 2008

Monday, September 29, end of week 5, Generic Functions and Classes in C++

Page 2: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Fixed types in containers

• Fixed types in containers present a problem• Containers can contain only 1 kind of application value.• You cannot use a linked list of strings to store a

sequence of ints or other application types.class sequence_linkedlistimpl : public sequence_interface { …

struct listelement { // private local helper class string *content ; bool deleteFlag ; listelement *next } *first ; int count ; }

Page 3: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Void *’s are an old, unsafe solution

• Unknown types present a different problem• (void *) cast when storing a pointer is safe.• How about casting from a (void *) to another pointer

type when retrieving data?class sequence_linkedlistimpl : public sequence_interface { …

struct listelement { // private local helper class void *content ; bool deleteFlag ; listelement *next } *first ; int count ; }

Page 4: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

C++ templates for generic functions and templates

• Suppose you want to define a linked list or other container class that can contain different data types when used by different client modules.

• sequence of “string *” as in our current assignment• sequence of “int” or “double” for another application• sequence of other C++ object types

• You may also want to do this for functions• sum() to add integers or to concatenate strings

Page 5: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Templates have variables for types

• A C++ template makes one or more types into variables when writing a library function or class.

• You can write a single library that works with different client types for different client “calls” to that library.• Each client call to the library binds the template type

variable to a fixed type.

• Templates allow you to reuse an algorithm or class without rewriting type-dependent code.

Page 6: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Example: a function that sums different types of parameters

• The recursive bisection algorithm of the last assignment could sum integers, sum doubles precision floats, concatenate strings, . . .

int sum(int count, int iarray[]) { if (count == 0) { return 0 ; } else if (count == 1) { return iarray[0] ; } else { int midpoint = count / 2 ; return sum(midpoint, iarray) + sum(count-midpoint, iarray+midpoint);}}

Page 7: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Use an ElemType array, where ElemType varies

template <typename ElemType>ElemType sum(int count, ElemType values[], ElemType nullvalue) { ElemType result ; if (count == 0) { result = nullvalue ; } else if (count == 1) { result = iarray[0] ; } else { int midpoint = count / 2 ; result = sum(midpoint, iarray, nullvalue) + sum(count-midpoint,

iarray+midpoint, nullvalue); } return result ; }

Page 8: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Client code binds ElemType when the client code compiles

~parson/DataStructures/template_sum:int *intarray = new int [ argc-1 ];double *dblarray = new double [ argc-1 ];string *strarray = new string [ argc-1 ];int isum = sum(argc-1, intarray, 0);double dsum = sum(argc-1, dblarray, 0.0);static const string nullstring("");string strsum = sum(argc-1, strarray, nullstring);

Page 9: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Standard Template Library

• The C++ Standard Template Library (STL) provides a set of template classes and functions for supporting access to structured data, along with support for common basic tasks.

• Containers such as sets, vectors, lists, and tables• Iterators are adjunct classes to Containers that allow

client code to step through a Container’s contents – they act like pointers, but do not violate encapsulation• Algorithms and function objects such as sorting

Page 10: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

STL References

• http://www.cplusplus.com/• http://www.cppreference.com/• http://www.sgi.com/tech/stl/

• Accessible from my CSC237 course page

• Containers and iterators come in several abstract flavors

• input_iterator, output_iterator, forward_iterator, bidirectional_iterator, random_iterator, reverse_iterator and compatible Container types

Page 11: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

STL-based vector implementation of sequence_interface

<<interface>> sequence_interface

sequence_stl_vectorimpl insert(), remove()get(), size()

private: vector<string *> stringVector ; // Store and retrieve from here. vector<bool> deleteVector ; // isDeleteLater flags

vector does conceptual array expansion/contraction for you.

Page 12: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

basic vector and vector::iterator indexing operations

• int count = stringVector.size();• vector<string *>::iterator stringIterator

= stringVector.begin(); // acts like a pointer

• advance(stringIterator, 1); // stringIterator++ ;

• stringIterator += realoff ;// advance(stringIterator, realoff)

• while (stringIterator != stringVector.end())

Page 13: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

vector and vector::iterator access and mutation operations

• *stringIterator accesses or modifies the element at which stringIterator “points”

• stringVector.insert(stringIterator, value);• stringVector.erase(stringIterator);• string * result = stringVector.at(realoff);• vector::iterator is a random iterator

Page 14: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

STL list and slist

• slist is STL’s equivalent of our singly-linked list; list is doubly-linked

• slist uses a forward iterator, while list uses a bidirectional iterator

• begin() and end() return iterators to the beginning and end, as with other Containers

• Forward iterator supports ++ operation, and bidirectional iterator adds -- operation

Page 15: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Tail recursive definitions of a List

• List := Node | Node List• What problem results from this definition?• What kind of List can you NOT represent?• How might you fix this problem?• Hint: Restate above as List := [Node] | [Node] + List

• List :=

Page 16: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Disadvantages of exposing implementation to client code

• Suppose you give client code direct access to the struct listelement linked list, so that any client pointer to a listelement is a sequence.

• How must you implement negative offsets and test non-negative offsets for validity?

contents next contents next contents next start of a list start of a different list

Page 17: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Advantages of information hiding and data abstraction

contents next contents next contents next start of the list (first), count of nodesAbstracting the sequence and hiding the linked list lets

you use count to determine offset validity without searching the list.

You can still provide client code with the advantages of recursive lists by creating operations to clone sub-sequences.

Private operations can manipulate nodes directly.

Page 18: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Implementation alternatives“Partitioning the design space”

contents next contents next contents next start of the list (first), count of nodesSuppose you want to define member operation

virtual sequence_interface *clone(int offset)that copies a subsequence into a new object.Should you copy list nodes or create new ones?How might you deal with node and string

deletion in one linked list and not the other?

Page 19: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Implementation alternatives“Optimizing common use cases”

contents next contents next contents next start of the list (first), count of nodesSuppose a majority of client code accesses

comprise a series of get(offset) invocations, where offset is 0, 1, 2, . . . , n-1.

What can you do to accelerate this typical usage?Why is information hiding useful in this case?Do insert() or remove() create any hurdles?

Page 20: CSC 237 - Data Structures, Fall, 2008 Monday, September 29, end of week 5, Generic Functions and Classes in C++

Circular sequences

• Circular arrays use modulo addition for indices• index = (index + 1) % arraySize• index = (index – 1 + arraySize) % arraySize

• Circular linked lists point from the last to the first element

• Doubly linked lists link the list head and tail together in both directions

• They are especially useful for queues, also know as first-in first-out (FIFO) sequences.