Logistics • Project Exceptions II – Part 3 (block) due Sunday, Oct 30 • Functionality (10) • Use of framework (5) • Code Style (5) • Memoization (5) • Questions? Exam Exam 2 • Exam 2 • What it will cover – Thursday, October 27. – C++ classes • constructors • Inheritance • Operator overloading – Review Session – Templates • Tuesday, Oct 25 th / 9-10am (70-3435) – STL • Wednesday, Oct 26 th / 8-9pm (70-3445) – Memory Management Logistics Plan for this week • Final exam • I/O Week – Good news…bad news – Today: Exceptions – Good news – Tomorrow: Exceptions II • Last day of finals, November 18 th – Thursday: Exam 2 – Bad news • 8am-10am – Room • 01-3338 1
Before we begin Enter…the exception • Any questions? • Exceptions allow a method to tell the caller when an error has occurred – Many times it is the calling function that knows what to do when an error occurs. – Exceptions allow the caller to respond to the error rather than the method itself. – Different callers may wish to respond to particular errors differently. Throwing exceptions Catching Exceptions • Like in Java, C++ uses a try/catch block for • In C++, exceptions are thrown by using the catching exceptions. throw keyword. void f() – Unlike Java, there is not a Throwable class. { try { – In C++, any item can be thrown // call to a method that may throw something • Basic datatypes (int, float, etc.) } catch (Overflow) { • Class objects // code that handles an overflow error • Pointers to class objects ... } • References to class objects ... } Question: Catching exceptions Answer: Catching exceptions • CC and g++ flags as an error • Erroneous ordering: try {// something} catch (...) try {// something} { // handle anything} catch (MathError) { // it’ll never get here} catch (MathError) catch (Overflow) { // it’ll never get here} { // or here} catch (Overflow) { // or here} Both flag this as a warning 2
Question: Throwing things you shouldn’t Answer: Throwing things you shouldn’t void foo1 () throw (int){ throw 7;} • foo2 violated it’s specification • Unexpected handler will be called. void foo2 () throw (float) { foo1();} • Not catching == throwing up the stack main (int argc, char *argv[]) { try { foo2(); } • Note: did not convert to float! catch (int) { // do something } } Question: Throwing things you shouldn’t Question: Automatic type conversions void foo1 (){ throw 7;} void foo1 () throw (int){ throw 7;} void foo2 () throw (float) { foo1();} void foo2 () throw (float) { foo1();} main (int argc, char *argv[]) main (int argc, char *argv[]) { { try { try { foo2(); foo1(); } } catch (int) { // do something } catch (long) { // do something } } } Question: Is this a good idea? Answer: Automatic type conversions void f() • Sorry, Charlie { – C++ will NOT do automatic type conversions throw Overflow(); for exceptions. } void g() – This code will call terminate. { try { f (); } catch (MathError &E) { E.printMessage(); } } 3
Answer: Maybe yes, maybe no Any others? • Implementation may store/transmit exception specially. – I.e. not on stack • Your mileage may vary • Stroustrup claims it’s acceptable practice. Catching Exceptions Catching Exceptions void use_file (const char *name) • In C++, there is no finally section of the { try/catch block. FILE *f = fopen (…); try { • In Java, the finally code is executed // some file operation regardless of whether an exception was } catch (…) { caught. fclose (f); – Allows for cleanup of system resources. throw; } fclose(f); } Stack unwinding Stack unwinding • Advantageous to wrap system resource calls • When an exception is thrown in C++ into class objects. – Call stack is searched for first function to catch – The resource can be cleaned up during object the data thrown. destruction. • If none found, program will terminate. • If one is found: – All local variables from all methods on stack from method void use_file (const char *name) that threw the exception to that which caught it, will have { it’s destructor called. FileObject f (…) – Note that this is not true for objects allocated on the heap. // do something with f } 4
Exceptions and Constructors Exceptions and Constructors class X { • If an exception is thrown during the call to Y yy; an object’s constructor, only the data Z zz; members that have been completely public: constructed are destroyed. X ( char *foo, int bar) : yy (foo), zz (bar) {} … } Exceptions and Constructors Exceptions and Constructors class Y { • An object is not completely constructed private: until it’s constructor completes. int *p; – Beware of data members allocated on the heap void init(); public: Y (int s) { p = new int [s]; init();} ~Y () { delete [] p;} … } Exceptions and Constructors Exceptions and Constructors class Y { • Questions? private: vector<int> p; void init(); public: Y (int s) { p (s); init();} } 5
Using exceptions Using exceptions • Important safety tips (from Stroustrup, the • Important safety tips inventor of C++) – Assume that every exception that can be thrown – Use exceptions for error handling by a function will be thrown. – Throw an exception to indicate failure during – Don’t assume that exceptions will be derived construction from the “standard” exception class. – Use exception specifications (good style…in – Libraries should not terminate a program. style guide) Throw an exception instead. – Beware of dynamically allocated data members – Think about error handling early in a design when throwing an exception from a constructor Assertions Assertions #include <cassert> • Debugging mechanism to test condition at any point in the code void foo (int *p) – If condition is false, the program aborts and { dumps core. // At this point p should not be null assert (p != 0); – Useful for testing preconditions, postconditions … and invariant checks. } Assertions Exceptions vs. Assertions // constructor • Exceptions // // Preconditions: – Let the caller decide how to handle the error. // last & first are not empty (emptyString) // age is not negative • Assertions // Person::Person( string last, string first, int age, string – Aborts the program firstJobName ): lastName(last), firstName(first), currentAge(age), currentJob(0) – Debugging tool { assert( last != emptyString ); • Should not be included in the release version of assert( first != emptyString ); software. assert( age >= 0 ); if ( firstJobName != noJob ) { currentJob = new Job( firstJobName ); } } 6
Exceptions vs. Assertions Exceptions vs. Assertions • What about for testing preconditions? • My own humble philosophy – Use assertions for errors that are under your // push control, as a programmer. // – Use exceptions for error that are under the // Description: adds a new element to "the top of" the stack control of a user of the system or user of your // Arguments: the element to be added code. // Pre: stack is not full // Post: size has increased by one // Post: top is equal to the argument newElement // virtual void push( char newElement ) = 0; Exceptions • Questions? 7
Recommend
More recommend