CS11 – Introduction to C++ Spring 2013-2014 Lecture 8Local Variables string getUsername() { string user; cout << "Enter username: " << endl; cin >> user; return user; } ! What happens to user when function returns? " It gets cleaned up automatically when the function returnsReturning References string & getUsername() { string user; cout << "Enter username: " << endl; cin >> user; return user; } ! Now, what does getUsername() return? " A reference to the local variable user " Big mistake – user goes away, then reference becomes invalid! ! Never return references (or pointers) to local variables! ! In general, be very careful when returning references. " The referenced object must outlive the caller’s use of itReferences and Arithmetic Operators ! From Lab 4B: // Implement + for sparse-vectors. const SparseVector & SparseVector::operator+( const SparseVector &rhs) const { return SparseVector(*this) += rhs; } ! Does this work? " This also returns a reference to a local variable. " More subtle, since the variable is an unnamed temporary " Will eventually result in a catastrophic failure of some kind ! Simple arithmetic operators should always return a const-object value (e.g. const SparseVector)Multiple Header Files ! Lab 6 has 13 classes in two header files: " Expression etc. - expressions.hh " Command etc. - commands.hh ! Managing relationships between header files can be annoying! " Commands depend on expressions " Other files depend on both of these " Easily leads to “multiple declaration” errorsHeader Files and Multiple Inclusion ! Can’t declare something multiple times! " Classes, functions, variables, … " Generates compiler errors. ! Solution is to use include-guards " Use the C++ preprocessor to make sure that each include file’s contents are only included once. " Uses the preprocessor directives: ! #ifndef – if not defined … ! #define – define some symbol … ! #endif – end of #ifdef, #ifndef, or #if preprocessor blockThe Preprocessor ! Preprocessor directives start with # character ! Performs simple text-level processing before the actual compilation phase begins " Inclusion of named files ! #include "expressions.hh" " Macro substitution ! #define MAX_SPEED 65 ! Our old friend assert(...) is also a macro " Conditional compilation ! Can optionally include or exclude chunks of code ! Great for writing applications that run on multiple platformsInclude-Guards ! Enclose contents of include file with a guard #ifndef SOMEFILE_HH #define SOMEFILE_HH ... // Normal header file contents #endif // SOMEFILE_HH " Comment after #endif is just for readability ! First time file is included, symbol isn’t defined. " Symbol will be defined on subsequent inclusions, so contents won’t be repeated. ! Choose a symbol name that is likely not to be used elsewhere! " Some variant of header file’s name is usually safeOther Header File Notes ! Results of preprocessing sometimes saved into temporary files " Not so often anymore, but common in the past! " If you are writing macros, may need to look at preprocessor output to debug your work " Most compilers provide a switch for that ! g++ -save-temps ... ! Including lots of header files can dramatically increase compile times " Only include header files that you need.Inside the assert() Macro ! C/C++ assert() macro uses the preprocessor #ifdef NDEBUG #define assert(e) ((void) 0) #else #define assert(e) \ ((void) ((e) ? 0 : __assert(#e, __FILE__, __LINE__))) ... // Definition of __assert() #endif ! If NDEBUG symbol is defined during compilation, assert() becomes a no-op " g++ -DNDEBUG ... " -D… defines the specified symbol when compilingInside the assert() Macro (2) ! C/C++ assert() macro: #ifdef NDEBUG #define assert(e) ((void) 0) #else #define assert(e) \ ((void) ((e) ? 0 : __assert(#e, __FILE__, __LINE__))) ... // Definition of __assert() #endif ! __FILE__ and __LINE__ are special symbols " Managed/updated by the preprocessor " __FILE__ is file currently being compiled (.cc or .hh) " __LINE__ is the current line of file being compiledInside the assert() Macro (3) ! C/C++ assert() macro: #ifdef NDEBUG #define assert(e) ((void) 0) #else #define assert(e) \ ((void) ((e) ? 0 : __assert(#e, __FILE__, __LINE__))) ... // Definition of __assert() #endif ! assert() returns no value: ((void) ...) ! expr ? true_val : false_val " A ternary (3-arg) operator, an “inline if-statement” " If expr is true, use true_val; otherwise use false_valInside the assert() Macro (4) ! C/C++ assert() macro: #ifdef NDEBUG #define assert(e) ((void) 0) #else #define assert(e) \ ((void) ((e) ? 0 : __assert(#e, __FILE__, __LINE__))) ... // Definition of __assert() #endif ! Finally, the definition contains no semicolons! ! Provided by the caller: assert(curr->value != 0);The C++ Standard Template Library ! Lab 7 is a brief introduction to the capabilities of the Standard Template Library (“the STL”) ! Generate a search index for a text document " Make a list of unique words " Keep a count of each word’s occurrences " Find out if a word appears in a set of stop-words ! The STL is a very powerful set of tools for managing and processing information " Definitely want to learn this library!What Is the STL? ! A set of generic containers, algorithms, and iterators that provide many of the basic algorithms and data structures of computer science. ! Generic " Heavily parameterized; lots of templates ! Containers " Collections of other objects, with various characteristics. ! Algorithms " For manipulating the data stored in containers. ! Iterators " “A generalization of pointers.” " Cleanly decouple algorithms from containers.Some STL Containers ! First category of containers: Sequences " Use indexing for access " Keep their values in a specific order ! vector – a growable array " Constant indexing, linear cost for insert/resize ! deque – double-ended queue " Constant prepend/append time, linear insert time ! list – a doubly linked list " Constant insert time, linear cost for indexing " Supports forward and backward traversal ! slist – a singly linked list " Only supports forward traversalMore STL
View Full Document