Thinking In C++. Volume 2: Practical Programming Preface Goals Chapters Exercises Exercise solutions Source code Language standards Language support Seminars, CD-ROMs amp; consulting Errors About the cover Acknowledgements Part 1.Building Stable Systems 1: Exception handling Traditional error handling Throwing an exception Catching an exception The try block Exception handlers Exception matching Catching any exception Re-throwing an exception Uncaught exceptions The terminate( ) function The set_terminate( ) function Cleaning up Resource management Making everything an object auto_ptr Function-level try blocks Standard exceptions Exception specifications The unexpected( ) function The set_unexpected( ) function Better exception specifications? Exception specifications and inheritance When not to use exception specifications Exception safety Programming with exceptions When to avoid exceptions Not for asynchronous events Not for benign error conditions Not for flow-of-control You’re not forced to use exceptions New exceptions, old code Typical uses of exceptions When to use exception specifications Start with standard exceptions Nest your own exceptions Use exception hierarchies Multiple inheritance (MI) Catch by reference, not by value Throw exceptions in constructors Don’t cause exceptions in destructors Avoid naked pointers Overhead Summary Exercises 2: Defensive programming Assertions A simple unit test framework Automated testing The TestSuite Framework Test suites The test framework code Debugging techniques Trace macros Trace file Finding memory leaks Tracking new/delete and malloc/free Summary Exercises Part 2.The Standard C++ Library 3: Strings in depth What’s in a string? Creating and initializing C++ strings Operating on strings Appending, inserting, and concatenating strings Replacing string characters Concatenation using nonmember overloaded operators Searching in strings Finding in reverse Finding first/last of a set of characters Removing characters from strings Comparing strings Strings and character traits A string application Summary Exercises 4: Iostreams Why iostreams? Iostreams to the rescue Inserters and extractors Common usage Line-oriented input Overloaded versions of get( ) Reading raw bytes Handling stream errors Stream state Streams and exceptions File iostreams A File-Processing Example Open modes Iostream buffering Seeking in iostreams String iostreams Input string streams Output string streams Output stream formatting Format flags Format fields Width, fill, and precision An exhaustive example Manipulators Manipulators with arguments Creating manipulators Effectors Iostream examples Maintaining class library source code Detecting compiler errors A simple data logger Generating test data Verifying and viewing the data Internationalization Wide Streams Locales Summary Exercises 5: Templates in depth Template parameters Non-type template parameters Default template arguments Template template parameters The typename keyword Typedef-ing a typename Using typename instead of class Using the template keyword as a hint Member Templates Function template issues Type deduction of function template arguments Function template overloading Taking the address of a generated function template Applying a function to an STL sequence Partial ordering of function templates Template specialization Explicit specialization Partial Specialization Partial ordering of class templates A practical example Preventing template code bloat Name lookup issues Names in templates Templates and friends Friend templates Template programming idioms Traits Policies The curiously recurring template pattern Template metaprogramming Compile-time programming Compile-time looping Loop unrolling Compile-time selection Compile-time assertions Expression templates Template compilation models The inclusion model Explicit instantiation The separation model Summary Exercises 6: Generic algorithms A first look Predicates Stream iterators Algorithm complexity Function objects Classification of function objects Automatic creation of function objects Adaptable function objects More function object examples Function pointer adapters Writing your own function object adapters A catalog of STL algorithms Support tools for example creation Filling and generating Example Counting Example Manipulating sequences Example Searching and replacing Example Comparing ranges Example Removing elements Example Sorting and operations on sorted ranges Sorting Locating elements in sorted ranges Example Merging sorted ranges Example Set operations on sorted ranges Example Heap operations Applying an operation to each element in a range Examples Numeric algorithms Example General utilities Creating your own STL-style algorithms Summary Exercises 7: Generic containers Containers and iterators STL reference documentation A first look Containers of strings Inheriting from STL containers A plethora of iterators Iterators in reversible containers Iterator categories Input: read-only, one pass Output: write-only, one pass Forward: multiple read/write Bidirectional: operator-- Random-access: like a pointer Is this really important? Predefined iterators More on stream iterators Manipulating raw storage The basic sequences: vector, list, deque Basic sequence operations vector Cost of overflowing allocated storage Inserting and erasing elements deque Converting between sequences Cost of overflowing allocated storage Checked random-access list Special list operations list vs. set Swapping basic sequences set A completely reusable tokenizer stack queue Priority queues Holding bits bitsetlt;ngt; vectorlt;boolgt; Associative containers Generators and fillers for associative containers The magic of maps Multimaps and duplicate keys Multisets Combining STL containers Cleaning up containers of pointers Creating your own containers STL extensions Non-STL containers Summary Exercises Part 3: Special Topics 8: Runtime type identification Runtime casts The typeid operator Casting to intermediate levels void pointers Using RTTI with templates Multiple inheritance Sensible uses for RTTI A trash recycler Mechanism and overhead of RTTI Summary Exercises 9: Multiple inheritance Perspective Interface inheritance Implementation inheritance Duplicate subobjects Virtual base classes Name lookup issues Avoiding MI Extending an interface Summary Exercises 10: Design patterns The pattern concept The Singleton Variations on Singleton Classifying patterns Features, idioms, patterns Building complex objects Factories: encapsulating object creation Polymorphic factories Abstract factories Virtual constructors Destructor operation Observer The "inner class" idiom The observer example Multiple dispatching Multiple dispatching with Visitor Exercises 11: Concurrency Motivation Concurrency in C++ Installing ZThreads Defining Tasks Using Threads Creating responsive user interfaces Simplifying with Executors Yielding Sleeping Priority Sharing limited resources Ensuring the existence of objects Improperly accessing resources Controlling access Simplified coding with Guards Synchronizing entire classes Thread local storage Terminating tasks Preventing iostream collision The ornamental garden Atomic operations Terminating when blocked Thread states Becoming blocked Interruption Blocked by a mutex Checking for an interrupt Cooperation between threads Wait and signal Producer-consumer relationships Solving threading problems with queues Proper toasting Broadcast Deadlock Summary Exercises A: Recommended reading General C++ Bruce’s books Chuck’s books In-depth C++ Design Patterns B: Etc Index Notes 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
Goals Our goals in this book are to:.
1. Present the material a simple step at a time, so the reader can easily digest each concept before moving on.
2. Teach «practical programming» techniques that you can use on a day-to-day basis.
3. Give you what we think is important for you to understand about the language, rather than everything we know. We believe there is an «information importance hierarchy,» and there are some facts that 95% of programmers will never need to know, but that would just confuse people and add to their perception of the complexity of the language. To take an example from C, if you memorize the operator precedence table (we never did) you can write clever code. But if you have to think about it, it will confuse the reader/maintainer of that code. So forget about precedence, and use parentheses when things aren’t clear. This same attitude will be taken with some information in the C++ language, which is more important for compiler writers than for programmers.
4. Keep each section focused enough so the lecture time—and the time between exercise periods—is small. Not only does this keep the audience’ minds more active and involved during a hands-on seminar, but it gives the reader a greater sense of accomplishment.
5. We have endeavored not to use any particular vendor’s version of C++. We have tested the code on all the implementations we could, and when one implementation absolutely refused to work because it doesn’t conform to the C++ Standard, we’ve flagged that fact in the example (you’ll see the flags in the source code) to exclude it from the build process.
6. Automate the compiling and testing of the code in the book. We have discovered that code that isn’t compiled and tested is probably broken, so in this volume we’ve instrumented the examples with test code. In addition, the code that you can download from http://www.MindView.net has been extracted directly from the text of the book using programs that also automatically create makefiles to compile and run the tests. This way we know that the code in the book is correct.