CS3101-2, Lecture 5 CS3101-2 Programming Languages – C++ Lecture 5 Matthew P. Johnson Columbia University Fall 2003
Transcript
Slide 1
CS3101-2, Lecture 5 CS3101-2 Programming Languages C++ Lecture
5 Matthew P. Johnson Columbia University Fall 2003
Slide 2
CS3101-2, Lecture 5 Agenda hw3 was due last night Today:
Templates Exceptions Other odds and ends The STL Grading and the
final hw4 TBA tonight
Slide 3
CS3101-2, Lecture 5 Templates Often want to do basically the
same thing with different things functions work on variables only
types specified algorithmic thinking computer science functionalism
in phil. of mind abstraction human = the rational animal
(Aristotle) Sometimes want to do basically the same thing with
different types of things Queue of ints, queue of widgets abstract
data types
Slide 4
CS3101-2, Lecture 5 max functions Suppose want the max of two
numbers What kind of numbers? ints chars floats doubles All!
How?
Slide 5
CS3101-2, Lecture 5 max functions Soln 1: Write one, maxly
general function double max(double a, double b) { return a > b ?
a : b; } double x = max(2.5, 3.5); char c = (char)max(A,B); This
works but its not nice All four types can widen to doubles but must
be cast back
Slide 6
CS3101-2, Lecture 5 max functions Soln 2: Write one function
for each type int max(int a, int b) { return a > b ? a : b; }
double max( etc. Is allowed in C++ (though not in C) But manually
duplicating code for nontrivial ftns bad hard to maintain
Slide 7
CS3101-2, Lecture 5 max functions Soln 3: Use the C
preprocessor macros #define max(a,b) (a > b ? a : b) C source
code is preprocessed #include s replaced with header files #ifndef,
etc. macro calls replaced with macro content int c = max(2,3); int
c = (2 > 3 ? 2 : 3); Works too, but complications, e.g.: z =
max(x++, y++) z = (x++ > y++ ? x++ : y++) x, y inc-ed twice Need
many parens sq(a+b), etc.
Slide 8
CS3101-2, Lecture 5 max functions Soln 4: Use the CPP in a more
sophisticated way Dont use the CPP to generate expressions but to
generate functions #define define_max(t)\ t max(t a, t b) {\ return
a > b ? a : b;\ } define_max(char) define_max(int) etc. no ;
Avoids prev. CPP problems But reqs code for all poss types Done
manually
Slide 9
CS3101-2, Lecture 5 Templates template result ftn(param-list)
{} The place-holder for the substituted type is t template and
class are used as keywords can use typename in place of class T is
a type Primitive or class All occurrences in ftn replaced with real
type
Slide 10
CS3101-2, Lecture 5 max functions Soln 5: use templates
parameterized function expands per type as necessary template T
max(T a, T b) { return a > b ? a : b; } Now can simply call the
ftn: x = max(2.5,3.5); Compiler autoly creates only the ftn
specializations needed
Slide 11
CS3101-2, Lecture 5 Sorting things Consider problem of sorting:
Sorting ints Sorting doubles Sorting strings Sorting widgets Point
of sorting: put list in order Q: What does in order mean? A: Given
an ordering relation < on the members For x and y, tells whether
x < y Reorder s.t. x is before y iff x < y
Slide 12
CS3101-2, Lecture 5 Generic sorting Sort alg doesnt depend of
element type Merge sort, quick sort, etc. Need only give means to
compare to elms How? In C we pass in a pointer to a compare ftn:
void qsort(void *base, int n, int size, int (*cmp)(const void *,
void *)); Pass in pointer to ftn: int cmp(const void *a, void *b) {
Widget* w1 = (Widget*)a; } Works, but very awkward
Slide 13
CS3101-2, Lecture 5 Generic sorting In Java, we pass a
Comparable implementer In the sort ftn we say if (a.compareTo(b)
< 0) // means a < b Objects must implement this interface
compare with ftn call Primitives cant implement Compared with ops
could put in wrappers
Slide 14
CS3101-2, Lecture 5 Generic sorting C++ soln 1: Define our own
Comparable analog: abstract class Has virtual compareTo Or, better:
has virtual operators Any class extending our class can now be
sorted Pass in array of Comparable-extending objects Sort uses
polymorphism to treat as (mere) Comparables Downside: can only sort
objects if they extend Comparable Mult inher: can always add Comp
parent, but must do so To sort primitives must create wrapper
classes
Slide 15
CS3101-2, Lecture 5 Generic sorting C++ soln 2: use templates!
Let sort take an array of some arb. kind Dont need Comparable Dont
need compareTo In sort, just say if (a < b) If these are
numbers, this works If these are objects that overload ops, this
works Only requirement: kind supports ops
Slide 16
CS3101-2, Lecture 5 Templates: swapping Remember our
swap-with-ptrs ftn? void swap(int &a, int &b) { int temp c
= a; a = b; b = a; } Suppose we want to swap other types
templates
Slide 17
CS3101-2, Lecture 5 Generic swapping template void swap(T
&a, T &b) { T temp c = a; a = b; b = a; } Now can swap any
prim Can also swap any objects As long as = op is public
Slide 18
CS3101-2, Lecture 5 Fancier swapping Remember our fancier swap
ftn? void swap(int &a, int &b) { a ^= b ^= a ^= b; }
Fancier template function: template void swap(T &a, T &b) {
a ^= b ^= a ^= b; } Now can swap ints, chars, longs But: cannot
swap objects Unless their ^= is overloaded unlikely
Slide 19
CS3101-2, Lecture 5 Template specialization string s,t
max(s,t); works But max(hi,there) doesnt: if (hi < there)
compares two pointers - where the char[] s start Not what we mean
Soln: create a specialization special version for this case We
check for spec. before template char *max(char *a, char *b) {
return strcmp(a,b) > 0 ? a : b; }
Slide 20
CS3101-2, Lecture 5 Class templates Couple weeks ago: wrote a
stack class supported only integers Well abstract element type away
Abstract data types Only changes to declar: 1. prepend on class
dfn: template class className {} 2.Replace int T For ftn implems,
we 1. prepend the same 2. replace className with className 3.
Replace int T template void Stack ::push(const T elm){} To
instantiate: Stack strStack;
Slide 21
CS3101-2, Lecture 5 Class specialization Similarly, can
specialize member functions of class templates: void stack
::push(const char *const item) { data[count++] = item; }
Slide 22
CS3101-2, Lecture 5 Templates & statics Review: static data
members one inst shared by all class insts What about statics in
templates classes? Q: Could one inst be shared by all insts? A: No
consider: template class C { static T mem; } mem couldnt me shared
by all insts shared by all insts But: for C, mem shared by all C
insts
Slide 23
CS3101-2, Lecture 5 Templates & friends Given class, can
declare some outside ftn or class its friend We have a stack class
Suppose: want to declare external sort ftn its friend Before: had
stack with ints could use sort ftn based on ints Now: have Stack
friend is template too template class Stack { friend void C ::f5(X
);
Slide 24
CS3101-2, Lecture 5 Odds and ends: Forward declarations Suppose
classes Cat and Dog each depend on each other class Cat { void
look(Dog d) { cout ioiter Enter two nums: 5 6 T">
CS3101-2, Lecture 5 I/O iterators ioiter.cpp Code: int x =
*intIn; intIn++; x += *intIn; Output: C:\3101-2\lec5>ioiter
Enter two nums: 5 6 The sum is: 11 But if code: int x = *intIn;
/*intIn++;*/ x += *intIn; Then output: C:\3101-2\lec5>ioiter
Enter two nums: 5 6 The sum is: 10
Slide 50
CS3101-2, Lecture 5 copy function vect2.cpp Another way to
print container: use copy function if (!vect.empty()) {
ostream_iterator out(cout, " "); copy(vect.begin(), vect.end(),
out); } copy(src begin it, src end it, dest it); src begin it:
vect.begin() src end it: vect.end() dest it: ostream_iterator
out(cout, " ") its an ostream_iterator its wrapping around cout its
outputting T s its printing between the T s
Slide 51
CS3101-2, Lecture 5 shuffle, sort, search, min vect2.cpp void
sort(begin it, end it) it-s must be random-access members must
support ==, < void random_shuffle(begin it, end it) same reqs
bool binary_search(begin, end, target) same reqs also: assumes
sorted min_element(v.begin(), v.end()) returns iterator
Slide 52
CS3101-2, Lecture 5 shuffle, sort, search, min vect3.cpp All
ftns translate automatically to strings transform ftn vect4.cpp
transform(begin it, end it, dest it, ftn) transform(v.begin(),
v.end(), v.begin(), square); cout