Title: CS242N Lecture 3 Adam Mitz mitzcse'wustl'edu Dept' of Computer Science and Engineering Washington Un
1CS242N Lecture 3Adam Mitz (mitz_at_cse.wustl.edu)
Dept. of Computer Science and EngineeringWashingt
on University in St. Louis
- Advanced Features
- Exceptions, Templates and the Standard Template
Library
2Outline
- Enumerated Types enums
- Type Aliasing typedef
- Exceptions
- Templates
- Adding Templates and Exceptions to the Stack
Example - Using the Stack to make a calculator
- Generic Programming Paradigm
- The Standard Template Library
3Enumerated Types enums
- Enumerated Types are collections of integer
constants. - enum Season WINTER, SPRING, SUMMER, AUTUMN
- Season can be used as a type for variables,
parameters, etc. - The members have the integer values 1, 2, 3
(custom assignments are allowed). - An implicit conversion from the enum type to int
is allowed.l
4Type Aliasing typedef
- Typedef statements in C/C create aliases of
types. - typedef int Integer
- Now Integer can be used where int would
normally be used. - Can make complex syntax shorter (examples
arrays, function pointers) - Not a good idea in general (makes code hard to
read) - Can be useful with templates (as well see later)
5Exceptions
- Unlike in Java, any object (including primitives)
can be thrown. - throw/try/catch syntax is the same
- No need for new after throw (use stack)
- No finally clause (destructor of stack object can
do the same thing) - Catch-all catch() / code /
- Re-throw throw (within catch block)
- Exception objects should be caught by-reference
in most cases. - No need to declare exceptions (throws in
Java), but it is possible to.
6Templates
- Templates are a compile-time feature of C.
(Type checking is done.) - Functions or classes can be made templates. They
are declared with one or more types left
unspecified. - Example
- template lttypename Tgt
- void swap(T a, T b)
- T t(a) ab bt
- Use int x, y swap(x, y)
- Compile-type polymorphic functions/types
7Template Classes
- Example
- template lttypename Tgt
- class Box public T value
- Use
- Boxltintgt bi bi.value 42
- Must declare objects with template type provided
in lt gt s. - Put it in files named Box_T.H, cc
- At the end of .H, include .cc file
- Do not add this to the Makefile
8Stack Version 2 Templates
- Week 1s version of the Stack class was limited,
it only handled ints as data. - Using templates, make a generic Stack that can
hold data of any type. - Templates are used in this manner for all
containers in C - Theres no Object overall superclass.
9Stack Version 2 Exceptions
- Our Stack program should throw exceptions on
error conditions - peeking an empty stack
- popping an empty stack
- We could define our own exception classes
- Or use pre-defined underflow_error (defined in
the Standard Library) - Client code can catch underflow_error, or one of
its base classes runtime_error, or exception - These are in header file ltstdexceptgt
10StackItem_T.H
- ifndef STACKITEM_T_H
- define STACKITEM_T_H
- template lttypename Tgt
- class StackItem
- public
- typedef T ITEMTYPE
- StackItem(const T d, StackItemltTgt n)
- StackItem(const StackItemltTgt si)
- StackItem operator(const StackItemltTgt si)
- StackItem()
- T getData() const
- return data
- StackItemltTgt getNext() const
- return next
- private
11StackItem_T.cc
- include "StackItem_T.H"
- include ltunistd.hgt
- include "debug.h"
- template lttypename Tgt
- StackItemltTgtStackItem(const T d, StackItemltTgt
n) - data(d), next(n)
-
- template lttypename Tgt
- StackItemltTgtStackItem(const StackItemltTgt si)
- data(si.data), next(si.next)
- if(next ! NULL)
- DEBUG_OUT("new StackItem")
- next new StackItemltTgt(next)
-
-
- template lttypename Tgt
- StackItemltTgt StackItemltTgtoperator(const
StackItemltTgt si) - data si.data
12Stack_T.H
- ifndef STACK_T_H
- define STACK_T_H
- template lttypename Tgt
- class StackItem
- template lttypename Tgt
- class Stack
- public
- typedef T ITEMTYPE
- Stack()
- Stack(const StackltTgt s)
- Stack operator(const StackltTgt s)
- Stack()
-
- void push(T n)
- T pop()
- T peek() const
13Stack_T.cc
- include ltunistd.hgt
- include "Stack_T.H"
- include "StackItem_T.H"
- include "debug.h"
- include ltstdexceptgt
- using namespace std
- template lttypename Tgt
- StackltTgtStack()
- headOfList(NULL)
-
- template lttypename Tgt
- StackltTgtStack(const StackltTgt s)
- headOfList(s.headOfList)
- if(headOfList ! NULL)
- DEBUG_OUT("new StackItem")
- headOfList new StackItemltTgt(headOfList)
-
-
- template lttypename Tgt
- StackltTgtStack()
- while(!isEmpty())
- pop()
-
- template lttypename Tgt
- void StackltTgtpush(const T n)
- headOfList new StackItemltTgt(n, headOfList)
- DEBUG_OUT("new StackItem")
-
- template lttypename Tgt
- T StackltTgtpop()
- if(isEmpty()) throw underflow_error(doh!)
- StackItemltTgt newHol
- headOfList-gtgetNext()
- int result headOfList-gtgetData()
- DEBUG_OUT("delete StackItem")
- delete headOfList
- headOfList newHol
14main.cc
- include ltiostreamgt
- include "Stack_T.H"
- using namespace std
- templatelttypename Tgt
- ostream operatorltlt(ostream os, StackltTgt st)
- while(!st.isEmpty())
- os ltlt st.pop() ltlt endl
- return os
-
- void testStack()
- Stackltintgt s1, s2
- for(int i5 igt0 i--)
- s1.push(i)
- Stackltintgt s3(s1), s4
- s2 s3
- s4 s2
- cout ltlt s1.peek() ltlt endl
int main(int, char) testStack() return
0
15Template Implementation Notes
- The template type is sometimes written as
template ltclass Tgt class Foo - Each method must be used in client code, or it
wont be compiled! - The unbound type T can be modified const T, T,
T, T, and used just like any normal type - More than 1 template parameter is allowed, use
commas - Methods can have additional parameters besides
those of the class
16Calculator Using Stack
- Keep a Stack of Token pointers
- Whats a Token?
- Abstract Base Class
- Keeps a refernce to the Stack itself
- Pure-virtual eval() function
- Derived Classes
- Operand (wraps an int)
- Operator (wraps an enum for - / )
- Each derived class implements eval()
17calc.cc
- include ltiostreamgt
- include ltstdexceptgt
- include "Stack_T.H"
- using namespace std
- class Token
- protected
- StackltTokengt stack
- public
- virtual int eval() 0
- virtual Token()
-
- enum OperType PLUS, MINUS, TIMES, DIVIDE,
- MOD
- class Operator public Token
- public
- Operator(StackltTokengt st, OperType op)
class Operand public Token public
Operand(StackltTokengt st, int val)
Token(st), value(val) int value int
eval() return value int main(int,
char) StackltTokengt stack st.push(new
Operand(st, 6)) st.push(new Operand(st,
4)) st.push(new Operand(st, 5)) st.push(new
Operator(st, PLUS)) st.push(new Operator(st,
TIMES)) cout ltlt st.pop()-gteval() ltlt
endl //prints 54
18Generic Programming Paradigm
- The library provides containers that hold and
organize data, and algorithms that act on that
data. - How can we write algorithms that work with any
container? Even those not yet written? - Object-Oriented Require the containers to
implement a common interface - Generic Require the containers to model a
concept (more vague/flexible)
19The Standard Template Library
- The STL uses this generic programming paradigm.
- Example Concepts
- ForwardContainer, RandomAccessContainer,
Sequence, AssociativeContainer, OutputIterator,
BidirectionalIterator, BinaryFunction, Assignable - Concepts are the types of template parameters.
- Consider
- templateltclass InputIterator, class
UnaryFunctiongt - UnaryFunction for_each(InputIterator first,
InputIterator last, UnaryFunction f)
20The Iterator Concept
- Iterators are the bridge from containers to
algorithms. - Containers have functions like begin() and end()
which return iterators. - Algorithm functions take iterators as parameters,
specifing over which range to operate. - Thus the algorithm has no knowledge of the
container, only the iterators. - Iterators generalize pointers. They can be
incremented, dereferenced, and compared - Pointers, even though they arent objects of
classes, do model the Iterator concept
21Iterator Ranges
- Remember how arrays are indexed
- We refer to the start of the array as 0
- We refer to the end of the array as N
- We refer to the elements as numbers in the range
0, N-1 - Iterators are made to work the same way.
- A range is specified by two iterators, begin()
and end(). - begin() initially points to the start of the
range - end() points 1 element past the end of the range
- for(iterbegin() iter ! end() iter)
- / ... get the current object with (iter) /
22Containers
- Sequences
- vector, deque, list
- Associative
- set, map, multiset, multimap, hash_
- Adapters
- stack, queue, priority_queue
- Strings
- basic_string (shows up as string in users
code, this is a typedef)
23Algorithms
- Non-mutating
- for_each, find, find_if, adjacent_find,
find_first_of, count, count_if, mismatch, equal,
search, search_n, find_end - Mutating
- copy, copy_backward, swap, iter_swap,
swap_ranges, transform, replace, fill, generate,
remove, unique, reverse, rotate, random_shuffle,
random_sample, partition - Sorting
- sort, is_sorted, binary_search, merge, set_union,
push_heap, min, max
24Function Objects Functors
- When we call the sort() algorithm, we need to
tell it something about how the elements should
be ordered. - We pass it a function object, which it later
applies to pairs of elements. The function
returns positive, zero, or negative indicating
which is smaller. - Lessltintgt L
- sort(c.begin(), c.end(), L)
- How does it work? The functor class overrides
the () operator so its objects work like
functions.