Presentation is loading. Please wait.

Presentation is loading. Please wait.

L7: Exceptions Problem Description Error Handling –terminate the program –return a value representing an error –return a legal value and leave the program.

Similar presentations


Presentation on theme: "L7: Exceptions Problem Description Error Handling –terminate the program –return a value representing an error –return a legal value and leave the program."— Presentation transcript:

1 L7: Exceptions Problem Description Error Handling –terminate the program –return a value representing an error –return a legal value and leave the program in an illegal state –call an error-handling routine –use exceptions Use inheritance to implement exceptions Resource Management Typeid Chapter 8 and 14 of Stroustrup

2 Exceptions See Chapter 8 and 14 of Stroustrup Library or class can detect run-time errors, but may not know what to do with them. Caller may know what to do with run-time error, but doesn't know how to detect them. What can be done?

3 Error Handling Possibilities include: –terminate the program –return a value representing an error –return a legal value and leave the program in an illegal state –call an error-handling routine –use exceptions

4 Terminate Program Default behaviour for uncaught exceptions in C++ Not appropriate for libraries

5 Error Value Return Often no plausible error value Inconvenient because error must be checked for every function call

6 Illegal State Behaviour of C library functions Global variable errno is set by library. Calling routine must explicitly check errno.

7 #include int main() { //if error, fopen returns NULL and sets errno FILE * f = fopen("filename", "r"); if (!f) // an error has occurred, check errno { // file doesn't exist if (errno==ENOENT) printf("No file\n"); // perror checks errno and prints message perror("An error occurred opening file"); exit(-1); }

8 Error Handling Routine Exceptions not meant to handle this case But error handling routine has to choose a mechanism for dealing with errors

9 #include void sighandler(int sig) { printf("received signal %d\n", sig); exit(-1); } int main() { // register the handler with a seg fault signal(SIGSEGV, sighandler); // do something to cause a seg fault delete (int*)-10; }

10 Exceptions Designed to support handling of errors and other exceptional conditions Non-local control structure based on stack unwinding An alternative to the usual return mechanism Some legitimate uses that are not related to errors

11 Stack Unwinding When an exception is thrown and control passes from a try block onto a handler, the C++ run time calls the destructors of all the automatic objects constructed since the beginning of the try block. This process is called stack unwinding.

12 Exceptions Exceptional does not necessarily mean –almost never happens, or –a disastrous event. Can be thought of as: –some part of the system couldn't do what it was asked to do So, don't use exceptions when errors can be handled locally.

13 Throw struct RangeError { int i; RangeError(int ii){i=ii;}; }; char to_char(int i) { if (i ::min() || i > numeric_limits ::max()) throw RangeError(i); return (char)i; }

14 Catch void g(int i) { try { char c = to_char(i); //... } catch (RangeError r) { cerr << can't convert << r.i << to char\n; }

15 Inheritance and Exceptions class Matherr {}; class Overflow : public Matherr {}; class Underflow: public Matherr {}; class Zerodivide: public Matherr {}; void f() { try { //... } catch (Overflow) {// handle overflow}; catch (Matherr) {// handle any other Matherr}; catch (...) {// handle any other exception}; }

16 Resource Management void use_file(const char *fn) { File *f = fopen(fn, r); try { // use f } catch (...) { fclose(f); throw; } fclose(f); }

17 Resource Allocation is Initialisation class FilePtr { private: FILE *p; public: FilePtr(const char *name, const char *a){ p = fopen(name, a);}; ~FilePtr(){if (p) fclose(p);}; };

18 Resource Allocation is Initialisation void use_file(const char *p) { FilePtr f(p, r); try { // use f } catch (...) { // handle exception }

19 typeid Given an object (or a variable), typeid operator retrieves the type of an object (or a variable) to which a pointer or a reference points. Can be used to discover things about the actual type (usually its name). An alternative to dynamic_cast.

20 Inheritance class Shape { public: virtual void draw() = 0; }; class Rectangle: public Shape { public: void draw() { cout << "draw a rectangle\n";}; }; class Circle : public Shape { public: void draw() { cout << "draw a circle\n"; }; };

21 Example 1: An Alternative to Downcasting void rotate(const Shape &shape) { if (typeid(shape)==typeid(Circle)) { cout << "rotate Circle\n"; } else if (typeid(shape)==typeid(Rectangle)) { cout << "rotate rectangle\n"; } Circle c; Rectangle r; rotate(c); // rotate Circle rotate(r); // rotate Rectangle

22 In the case of a polymorphic class (containing pure virtual functions), the typeid operator retrieves the most derived type of this object, if the argument of the typeid is an object (pointed by a pointer). If the argument is a pointer itself, the typeid operator regards the type of this object as the pointer of this class. Example 2

23 void f(Shape &circle, Shape *rectangle) { if(typeid(circle) == typeid(Circle)) cout << "a is of type Circle\n"; if(typeid(*rectangle) == typeid(Rectangle)) cout << "a is of type Rectangle\n"; Shape *s; if(typeid(rectangle) == typeid(s)) cout << "a is of type Shape\n"; } int main() { Circle c; Rectangle r; f( c, &r ); } Example 2

24 Example 3 In the case of a non-polymorphic class, the typeid operator retrieves the type of the object given. class C { public: C() {}; }; class D : public C { public: D() {}; };

25 Example 3 D d; C *c1 = &d; C &c2 = d; cout << "c1: " << typeid(*c1).name() << endl; // C cout << "c2: " << typeid(c2).name() << endl; // C


Download ppt "L7: Exceptions Problem Description Error Handling –terminate the program –return a value representing an error –return a legal value and leave the program."

Similar presentations


Ads by Google