1 / 68

CS3101-2 Programming Languages – C++ Lecture 5

CS3101-2 Programming Languages – C++ Lecture 5. Matthew P. Johnson Columbia University Fall 2003. Agenda. hw3 was due last night Today: Templates Exceptions Other odds and ends The STL Grading and the final hw4 TBA tonight. Templates.

lelia
Télécharger la présentation

CS3101-2 Programming Languages – C++ Lecture 5

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CS3101-2Programming Languages – C++Lecture 5 Matthew P. Johnson Columbia University Fall 2003 CS3101-2, Lecture 5

  2. Agenda • hw3 was due last night • Today: • Templates • Exceptions • Other odds and ends • The STL • Grading and the final • hw4 TBA tonight CS3101-2, Lecture 5

  3. 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” CS3101-2, Lecture 5

  4. max functions • Suppose want the max of two numbers • What kind of numbers? • ints • chars • floats • doubles • All! • How? CS3101-2, Lecture 5

  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 it’s not nice • All four types can widen to doubles • but must be cast back CS3101-2, Lecture 5

  6. 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 CS3101-2, Lecture 5

  7. max functions • Soln 3: Use the C preprocessor macros • #define max(a,b) (a > b ? a : b) • C source code is preprocessed • #includes 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. CS3101-2, Lecture 5

  8. max functions • Soln 4: Use the CPP in a more sophisticated way • Don’t 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 CS3101-2, Lecture 5

  9. Templates • template <class T> 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 CS3101-2, Lecture 5

  10. max functions • Soln 5: use templates • parameterized function • expands per type as necessary • template<typename T> 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 CS3101-2, Lecture 5

  11. 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 CS3101-2, Lecture 5

  12. Generic sorting • Sort alg doesn’t 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 CS3101-2, Lecture 5

  13. 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 can’t implement • Compared with ops • could put in wrappers… CS3101-2, Lecture 5

  14. 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 CS3101-2, Lecture 5

  15. Generic sorting • C++ soln 2: use templates! • Let sort take an array of some arb. kind • Don’t need Comparable • Don’t 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 CS3101-2, Lecture 5

  16. 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 CS3101-2, Lecture 5

  17. Generic swapping • template <class T>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 CS3101-2, Lecture 5

  18. Fancier swapping • Remember our fancier swap ftn? • void swap(int &a, int &b) { a ^= b ^= a ^= b; } • Fancier template function: • template <class T>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 CS3101-2, Lecture 5

  19. Template specialization • string s,t … max(s,t); works • But max(“hi”,”there”) doesn’t: • 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; } CS3101-2, Lecture 5

  20. Class templates • Couple weeks ago: wrote a stack class • supported only integers • We’ll abstract element type away • “Abstract data types” • Only changes to declar: • prepend on class dfn: • template <class T>class className {…} 2. Replace int T • For ftn implems, we • prepend the same • replace className with className<T> • Replace int T • template <class T> void Stack<T>::push(const T elm){} • To instantiate: • Stack<string> strStack; CS3101-2, Lecture 5

  21. Class specialization • Similarly, can specialize member functions of class templates: • void stack<char*>::push(const char *const item) { data[count++] = item; } CS3101-2, Lecture 5

  22. 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 T> class C { static T mem; … } • mem couldn’t me shared by all insts • shared by all insts • But: for C<int>, mem shared by all C<int> insts CS3101-2, Lecture 5

  23. 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<T> • friend is template too • template <class T> class Stack { friend void C<T>::f5(X<T>); … CS3101-2, Lecture 5

  24. Odds and ends: Forward declarations • Suppose classes Cat and Dog each depend on each other • class Cat { void look(Dog d) { cout << “Meow!\n”; } }; • class Dog { void look(Cat c) { cout << “Bark!\n”; } }; • Q: Will this compile? • A: No - Dog is referenced before declared • Soln: a forward declaration • Put class Dog; beforeCat def • Dog not yet complete but • Dog will now be recognized, w/o Cat depend. CS3101-2, Lecture 5

  25. Namespaces • int i; • namespace Example { double PI = 3.14; int i = 8; void printVals(); namespace Inner { int i = 9; } } // no semi-colon! • Can access: • Example::i, Example::Inner::i • printVals implementation: • void Example::printVals() { i is Example::i ::i is the global I } CS3101-2, Lecture 5

  26. Namespaces • Now: can use • Example • Example::Inner • Example::Inner::i • Example::i • Nested namespaces ~ Java packages • Unfortly: #include (CPP) / using (C++) independent • In general, use maximally narrow ranges • Prevent ambiguity • Don’t say using namespace std; • Or can fully specify reference: • std::std << std::endl; CS3101-2, Lecture 5

  27. assert • Old days: bad thing happens • writing to bad memory address • divide by 0, etc. •  core dump, maybe don’t notice, etc. • void Stack::push(const int item) { data[count++] = item; } • no room  overwrite wrong data, crash, etc. • Somewhat better: assert that everything is okay • assert(count >= 0 && count < sizeof(data)/sizeof(data[0])); • “Everything’s okay, right?” • If false, we quit with message of false expression CS3101-2, Lecture 5

  28. Exceptions • Now: to some extent • bad behavior is prevented • attempt  “exception” • If bad things happen • we halt, tell calling ftn • maybe it halts, tells its calling ftn • eventually, either • someone responds accordingly or • main ftn passes to OS • try – throw – catch • try to do something • maybe an exception gets thrown • if so, we may catch it, and go on CS3101-2, Lecture 5

  29. Exception handling • void Stack::push(const int item) throws BoundExp { if (count < 0 || count >= sizeof(data)/sizeof(data[0])) throw BoundExp(“stack overflow”); data[count++] = data; //ok if here } • What is BoundExp? • A class we define CS3101-2, Lecture 5

  30. Our exception • class BoundExp: exception { public: BoundExp(const string &s) exception(s) {} }; • NB: It’s just a class • Its parent is exception but needn’t be • Exception has what() • maybe other info CS3101-2, Lecture 5

  31. Throwing and catching • try { Stack s; … s.push(25); … } catch (BoundExp &exp) { cout << “Error: “ << exp.what() << ‘\n’; } catch (ExpType2 &exp) { // can catch mult kinds // only catch <= 1 … } catch (…) { // … is a wildcard! cout << “Unknown exception caught.\n”; } CS3101-2, Lecture 5

  32. Exception classes • <exception> exception • <stdexcept> • runtime_error, logic_error • bad_alloc: new failed • bad_cast: dynamic_cast failed • Can throw non-exception objs • And even primitives • But handling easer if don’t CS3101-2, Lecture 5

  33. STL • Ceteris paribus, libraries are good • Hard, subtle problems  many mistakes • don’t re-invent the wheel • Unless we’re wheel artists • better to commodify the wheel • Use an “off-the-shelf” wheel like everyone else • The standard wheel is reliable and efficient • STL == Starbucks of programming • Lots of important algorithms, data structures in CS • Barring good reason • use std versions CS3101-2, Lecture 5

  34. Standard Template Library • Many template classes, functions • Abstract data types • Three general categories: • Containers • Iterators • Algorithms • Three kinds of containers: • Sequences • Associative • Adapted CS3101-2, Lecture 5

  35. STL: “first-class” containers • Sequences: • vector: Dynamic-array-backed • const-time random-access • const-time insert/delete at back • deque: double-ended queue • fast random-access - how? • fast insert/delete at front and back • list: doubly-linked list • fast insert/delete anywhere • Associative: • set: non-sequential, unique • multiset: non-sequential, non-unique • map: maps from keys to unique values • multimap: maps to non-unique values CS3101-2, Lecture 5

  36. STL: containers • Container adapters: • use “first-class” containers by composition • stack: LIFO • queue: FIFO • priority_queue • Near-containers: • arrays • string • bitset • valarray CS3101-2, Lecture 5

  37. Container member ops & ftns • copy constructor • empty() • size() • swap • First-class: • begin() • end() • rbegin() • rend() • erase • clear() NB: These are allow very simple - little more than getters CS3101-2, Lecture 5

  38. STL Iterators • Standard way to traverse through container: iteration • Abstraction of both “index” and “pointer” • just: means of iterating • forward, back, etc. • Iterator direction types: • Forward iterator • Reverse iterator • both supported by vector, list, etc. • Random-access iterator • supported by vector • Also: its can be const or not CS3101-2, Lecture 5

  39. Types of iterators • I/O iterators are “one-pass” • can only move in one direction • can only traverse once – p++ • Other types: • bidirectional: p++, p-- • random-access: p + i, p - i, p[i] *(p+i), p1 < p2 • vector: random-access • deque: random-access • list: bidirectional • set/multiset: bidirectional • map/multimap: bidirectional CS3101-2, Lecture 5

  40. vector class • Most commonly used container class • Fast random access • random-access iterators • Can access mems • with []s like arrays – unsafe • with at(i) – checks bounds, throws exception – safer • Essentially: dynamic array hidden in obj • add to/delete from back: const time • unless run out of space •  autoly copy to larger array • insert/del from middle: linear time • must move half of mems forward/back CS3101-2, Lecture 5

  41. Vectors <vector> • Similar to Java’s Vector in that: • dynamic-array-backed list • same complexities • Different in that: • takes insts of specified type • vector<int> nums; • vector<double> vals(20); • size-20 vector of doubles • vector<Base> objs; • takes Base objects • vector<Base*> ptrs; • takes Base*s or Extended*s CS3101-2, Lecture 5

  42. Template errors can be illegible • Consider this ftn: • template <class T> void printReverse(const vector<T> &vect) { for (vector<T>::reverse_iterator curr = vect.rbegin(); curr != vect.rend(); curr++) cout << *curr << ","; } • Slightly different from before • how? CS3101-2, Lecture 5

  43. Template errors can be illegible • When compiled: • Error E2034 c:\Borland\Bcc55\include\rw/iterator.h 442: Cannot convert 'const int *' to 'int *' in function reverse_iterator<int *>::reverse_iterator(const reverse_iterator<const int *> &) • Error E2094 vect.cpp 19: 'operator!=' not implemented intype 'reverse_iterator<int *>' for arguments of type 'reverse_iterator<const int *>' in function printReverse<int>(const vector<int,allocator<int> > &) • Error E2034 c:\Borland\Bcc55\include\rw/iterator.h 442: Cannot convert 'const int *' to 'int *' in function reverse_iterator<int *>::reverse_iterator(const reverse_iterator<const int *> &) • Warning W8057 c:\Borland\Bcc55\include\rw/iterator.h 442: Parameter 'x' is never used in function reverse_iterator<int *>::reverse_iterator(const reverse_iterator<const int *> &) • *** 3 errors in Compile *** • Why? reverse_iterator not const_reverse_iterator CS3101-2, Lecture 5

  44. Vectors e.g. – vect.cpp • template <class T> ostream& op<<(ostream& out, const vector<T> &vect) { out << "("; for (int i = 0; i < vect.size(); i++) out << vect[i] << ","; out << ")"; return out; } • template <class T> void printReverse(const vector<T> &vect) { cout << "("; for (vector<T>::const_reverse_iterator curr = vect.rbegin(); curr != vect.rend(); curr++) cout << *curr << ","; cout << ")"; } CS3101-2, Lecture 5

  45. Vectors e.g. – vect.cpp • void main() { srand(time(NULL)); vector<int> ints; cout << "Initial size == " << ints.size() << "\nInitial capacity == " << ints.capacity(); for (int i = 0; i < 5; i++) ints.push_back(rand() % 20); cout << "\nNow, size == " << ints.size() << "\nCapacity == " << ints.capacity(); cout << "\nvector: " << ints; cout << "\nvector reversed: "; printReverse(ints); CS3101-2, Lecture 5

  46. Vectors e.g. – vect.cpp • try { ints.at(100) = 20; } catch (out_of_range oor) { cout << "\nTried to set mem 100,"; cout << "\nbut caught exception: " << oor.what(); } sort(ints.begin(), ints.end()); cout << "\nAfter sort, vect: “ << ints; • } CS3101-2, Lecture 5

  47. Vectors e.g. – vect.cpp • Initial size == 0 Initial capacity == 0 Now, size == 5 Capacity == 256 vector: (7,3,16,14,17,) vector reversed: (17,14,16,3,7,) • Tried to set mem 100 to 20, • but caught exception: index out of range in function: vector:: at(size_t) index: 100 is greater than max_index: 5 • After sort, vector: (3,7,14,16,17,) CS3101-2, Lecture 5

  48. STL interators – iterio.cpp • Access set of values from one place • Usually, place is a container • But: input stream may be construed as a place • #include <iostream> #include <iterator> • using namespace std; • void main() { cout << “Enter two nums: “; istream_iterator<int> intIn(cin); int x = *intIn; intIn++; x += *intIn; ostream_iterator<int> intOut(cout); cout << “The sum is: “; *intOut = x; cout << endl; } CS3101-2, Lecture 5

  49. 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 CS3101-2, Lecture 5

  50. copy function – vect2.cpp • Another way to print container: • use copy function • if (!vect.empty()) { ostream_iterator<T> 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<T> out(cout, " ") • it’s an ostream_iterator • it’s wrapping around cout • it’s outputting Ts • it’s printing “ “ between the Ts CS3101-2, Lecture 5

More Related