current = new Link<K,V>(k,def_val); current->pre = p->pre; current->suc = p; if (p == head) // head = current; else p->pre->suc = current; p->pre = current; return current->value; } Link<K,V>* s = p->suc; if (s == 0) { // p ( ) current = new Link<K,V>(k,def_val); current->pre = p; current->suc = 0; p->suc = current; return current->value; } p = s; } } , . , . . Map. current, . - : template<class K, class V> void Map<K,V>::remove(const K& k) { // . 2 $$8.10 } template<class K, class V> Map<K,V>::Map(const Map<K,V>& m) { // Map } template<class K, class V> Map& Map<K,V>::operator=(const Map<K,V>& m) { // Map } . Map - first(), last() element(const K&), , , - . , . Mapiter Map : template<class K, class V> class Mapiter { friend class Map<K,V>; Map<K,V>* m; Link<K,V>* p; Mapiter(Map<K,V>* mm, Link<K,V>* pp) { m = mm; p = pp; } public: Mapiter() { m = 0; p = 0; } Mapiter(Map<K,V>& mm); operator void*() { return p; } const K& key(); V& value(); Mapiter& operator--(); // void operator--(int); // Mapiter& operator++(); // void operator++(int); // }; key() value() Mapiter , . template<class K, class V> const K& Mapiter<K,V>::key() { if (p) return p->key; else return m->def_key; } template<class K, class V> V& Mapiter<K,V>::value() { if (p) return p->value; else return m->def_val; } ++ -- Map : Mapiter<K,V>& Mapiter<K,V>::operator--() // { if (p) p = p->pre; return *this; } void Mapiter<K,V>::operator--(int) // { if (p) p = p->pre; } Mapiter<K,V>& Mapiter<K,V>::operator++() // { if (p) p = p->suc; return *this; } void Mapiter<K,V>::operator++(int) // { if (p) p = p->suc; } , . , Mapiter , . Mapiter , Map: template<class K, class V> Mapiter<K,V>::Mapiter(Map<K,V>& mm) { m == &mm; p = m->head; } operator void*() , Map, . iter, , : void f(Mapiter<const char*, Shape*>& iter) { // ... if (iter) { // } else { // } // ... } - $$10.3.2. , key() value() . , , Map. : hammer 2 nail 100 saw 3 saw 4 hammer 7 nail 1000 nail 250 , , , , : hammer 9 nail 1350 saw 7 ------------------- total 1366 , . : template<class K, class V> void readlines(Map<K,V>&key) { K word; while (cin >> word) { V val = 0; if (cin >> val) key[word] +=val; else return; } } , readlines() : main() { Map<String,int> tbl("nil",0); readlines(tbl); int total = 0; for (Mapiter<String,int> p(tbl); p; ++p) { int val = p.value(); total +=val; cout << p.key() << '\t' << val << '\n'; } cout << "--------------------\n"; cout << "total\t" << total << '\n'; } 8.9  1. (*2) , , $$8.3. 2. (*3) String, . , lchar, . String, . 3. (*1.5) Record () -: count () price (). . Vector. 4. (*2) Map, -. 5. (*2) Map $$8.8, . 6. (*2.5) Map $$8.8, . $$6.2.3 . " " .1, "", 1978 [K]. 7. (*2) Map. Link , - . 8. (*3) $$8.8 , Map. - . , Map, , . 9. (*2.5) Map . [K] .1, . 323-332. (. 6). 10. (*2) $$8.8 , , (, "thumb back"). 11. (*2) , , (, , ). 12. (*2) Sort $$8.4.5, . . [K] .3, $$5.2.1 (. 6). 13. (*1) Map Mapiter , ++ -- Mapiter. 14. (*1.5) , $$8.4.5 , Vector<T> T[].  * 9 , . - , , . , . . . , , . 9.1  , . , . , , . . ++ , . , , , , , , . , , . Vector , : class Vector { int* p; int sz; public: class Range { }; // int& operator[](int i); // ... }; , Range , : int& Vector::operator[](int i) { if (0<=i && i<sz) return p[i]; throw Range(); } , , , try. : void f(Vector& v) { // ... try { do_something(v); // , v } catch (Vector::Range) { // Vector::Range // do_something() , // - // , // do_something() Vector::operator[]() // - } // ... } catch ( /* ... */ ) { // ... } , try, . catch. , , , , , , , (. $$9.3). do_something() ( Vector), , . , f(): void do_something() { // ... crash(v); // ... } void crash(Vector& v) { v[v.size()+10]; // } , . , , , . $$9.4. , , , . $$9.7. , , , . , , , . f() Vector::Range, f() : int ff(Vector& v) { try { f(v); // f() Vector::Range } catch (Vector::Range) { // // ... } } 9.1.1  . , Vector::operator[]() : [1] ; [2] , ""; [3] ; [4] , . [1] (" ") , . . [2] (" """) , "". , . , , . . . [3] (" ") , . , errno. , errno, , , . , , . , [4] ( " "). , , , . $$9.4.3. , , . , , , . . : ( ) . , - . , , "" , . - , ( , ). , , ($$9.3.2). . , , . , , , . , , ++, "" , , , . , , , , , , . 9.1.2  " " - , . ++ . , , . , (, ). , , , . , , , , . return. , ($$9.5). - . 9.2  , . , . , Vector : , : class Vector { int* p; int sz; public: enum { max = 32000 }; class Range { }; // class Size { }; // " " Vector(int sz); int& operator[](int i); // ... }; , Range, . Size, : Vector::Vector(int sz) { if (sz<0 || max<sz) throw Size(); // ... } Vector , (.. try) : void f() { try { use_vectors(); } catch (Vector::Range) { // ... } catch (Vector::Size) { // ... } } . , , : void f() { try { use_vectors(); } catch (Vector::Range) { // // : f(); } catch (Vector::Size) { cerr << " Vector::Size"; exit(99); } // , // Range } , break . case , , , (. $$9.8). : void f1() { try { f2(v); } catch (Vector::Size) { // ... } } void f2(Vector& v) { try { use_vectors(); } catch (Vector::Range) { // ... } } f2() Range, use_vectors(), Size f1(). . , , , , . : try { // ... } catch (input_overflow) { // ... throw input_overflow(); } input_overflow ( ) - . : try { // ... } catch (xxii) { try { // } catch (xxii) { // } } , , . 9.3  . , , . , . , , : class Vector { // ... public: class Range { public: int index; Range(int i) : index(i) { } }; // ... int& operator[](int i) // ... }; int Vector::operator[](int i) { if (o<=i && i <sz) return p[i]; throw Range(i); } , , : void f(Vector& v) { // ... try { do_something(v); } catch (Vector::Range r ) { cerr << " " << r.index << '\n'; // ... } // ... } catch . (.. ) , .. , . , . : template<class T> class Allocator { // ... class Exhausted { } // ... T* get(); }; void f(Allocator<int>& ai, Allocator<double>& ad) { try { // ... } catch (Allocator<int>::Exhausted) { // ... } catch (Allocator<double>::Exhausted) { // ... } } , : class Allocator_Exhausted { }; template<class T> class Allocator { // ... T* get(); }; void f(Allocator<int>& ai, Allocator<double>& ad) { try { // ... } catch (Allocator_Exhausted) { // ... } } , . . 9.3.1  . , Matherr, Overflow (), Underflow ( ) . Matherr , . Matherr , Overflow : enum { Overflow, Underflow, Zerodivide, /* ... */ }; try { // ... } catch (Matherr m) { switch (m) { case Overflow: // ... case Underflow: // ... // ... } // ... } , . : class Matherr { }; class Overflow: public Matherr { }; class Underflow: public Matherr { }; class Zerodivide: public Matherr { }; // ... , Matherr , . : try { // ... } catch (Overflow) { // Overflow } catch (Matherr) { // Overflow } Overflow , Matherr . , , catch (Matherr), . , Matherr. , . , (. $$9.3.2). . , , . : try { // ... } catch (Overflow) { /* ... */ } catch (Underflow) { /* ... */ } catch (Zerodivide) { /* ... */ } // ... , , - . , , , , . , , Matherr. . . , , , , . , . , . . , (. $$9.6.1). , , , : class network_file_err // : public network_err, // public file_system_err { // // ... }; network_file_err , : void f() { try { // - } catch (network_err) { // ... } } , : void g() { try { // - } catch (file_system_err) { // ... } } , , , g() , . , -. ANSI ISO ++ . (. $$9.3.2), , , . , Exception ( ), (. $$9.6). Exception, , . . 9.3.2  , , , , . , , , , , . . , . , "" , . : class Matherr { // ... virtual void debug_print(); }; class Int_overflow : public Matherr { public: char* op; int opr1, opr2;; int_overflow(const char* p, int a, int b) { cerr << op << '(' << opr1 << ',' << opr2 << ')'; } }; void f() { try { g(); } catch (Matherr m) { // ... } } Matherr m Matherr, g() Int_overflow. , , Int_overflow, . , . : int add(int x, int y) // x y { if (x > 0 && y > 0 && x > MAXINT - y || x < 0 && y < 0 && x < MININT + y) throw Int_overflow("+", x, y); // , // , // x y return x + y; } void f() { try { add(1,2); add(MAXINT,-2); add(MAXINT,2); // - } catch (Matherr& m) { // ... m.debug_print(); } } add , , , Int_overflow::debug_print(). , , Matherr::debug_print(). , , , . , : void h() { try { // - } catch (Matherr) { if (can_handle_it) { // , // } else { throw; // // } } } throw . , , , Matherr. , Int_overflow, h() Int_overflow, , h() Matherr : void k() { try { h(); // ... } catch (Int_overflow) { // ... } } . , ... " ", catch (...) : void m() { try { // - } catch (...) { // throw; } } : m() , , , , , . , , , . . : try { // ... } catch (ibuf) { // } catch (io) { // - } catch (stdlib) { // } catch (...) { // } : , , , ($$R.4.6). , , catch (...) , ($$R15.4). , ( ) , "" . 9.4  , , , , .., , . " " , . : void use_file(const char* fn) { FILE* f = fopen(fn,"w"); // f fclose(f); } , , , fopen() fclose(), , use_file(), fclose(). , , . , longjump() . , . : void use_file(const char* fn) { FILE* f = fopen(fn,"w");