cpsc 252 exception handling page 1 exceptions and exception handling client programmers can make...

16
CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class • attempting to dequeue an item from an empty queue • even though we have placed a precondition on the method Item_type Queue::dequeue( void ) // Pre: Queue is not empty • the client might not check before calling the dequeue() What should the dequeue() member function do?

Upload: melina-benson

Post on 27-Dec-2015

212 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 1

Exceptions and exception handling

Client programmers can make errors using a class

• attempting to dequeue an item from an empty queue

• even though we have placed a precondition on the method

Item_type Queue::dequeue( void )

// Pre: Queue is not empty

• the client might not check before calling the dequeue()

What should the dequeue() member function do?

More generally, what should any function do when an error arises?

Page 2: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 2

Possible ways to handle errors

• Do nothing and run the risk of severe problems such as a segmentation fault resulting in abnormal program termination

• Check for the error (the failing precondition) and return a default value if necessary and run the risk that the client programmer may never clue into the fact that something went wrong, leading to unexpected results (or worse) for the client code

• Check for the error condition and alert the client that something went wrong

Option 3 is by far the better approach!

How do we inform the client that something went wrong?

Page 3: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 3

Notifying the client

Terminate the program and optionally print an error message

if ( !count ) {

cerr << “Queue is empty” << endl;

exit (-1);

}

else

• not great because the client cannot recover

Have the function return a bool indicating successful/failure

bool enqueue( const Item_type& item )

• reasonable when we know failure is expected at some point

• but not when something unexpected happens only seldomly

Page 4: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 4

Or we can throw an exception…

C++ has a special mechanism for signaling failure

• any function can throw an exception when it detects an error

if ( count >= CAPACITY )

throw logic_error( “Queue is full” );

else

• this terminates the call to the function

• the client code then has the option of catching the exception

catch ( exception& e ) { [error handling] }

• the client might not catch the exception

• if it is not caught a default handler will terminate the program

Page 5: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 5

What is an exception? Is it an int? Is it a char?

In C++, any kind of object can be thrown as an exception

• usually the variable that is thrown is a class

• these are designed specifically to act as exceptions

• C++ defines a set of these classes in the standard library

• the declarations are in the header file <exception>

exception

logic_error runtime_error

Page 6: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 6

The what() method in the exception class

The exception class uses this to describe the error

• what() has the following signature

const char* what() const;

• what() returns a pointer to an error message

• the constructor has a string parameter for the message

We can create our own exception classes

• they are based on logic_error and runtime_error

• a logic_error indicates the client should know better

• a runtime_error indicates external cause

• a bad_alloc from new means no memory available

Page 7: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 7

We define an exception that can be thrown when the dequeue function is called on an empty queue

We will call this exception AccessViolation to indicate that we are trying to access an element that does not exist

#include <exception>

#include <stdexcept> // probably includes <exception>using namespace std;

class AccessViolation : public logic_error{ AccessViolation( void )

: logic_error( “Access violation” ) { }};

The what() method is declared in the exception class

Page 8: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 8

Now let’s think about how our dequeue() function will be written:

Item_type Queue::dequeue( void ){ if( isEmpty() ) // check if queue is empty throw AccessViolation();

// rest of function omitted, but it does // whatever we do if queue is not empty}

Here we call the constructor of the AccessViolation class to create an anonymous instance of the class and throw it

If the exception is thrown, the dequeue() function is terminated without executing any subsequent code in the function

Page 9: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 9

How the client uses the exceptiontry{ while( true ) // Horrible! Should be myQueue.dequeue(); // checking precondition!

}catch( exception& e ){ cout << “Exception: ” << e.what() << endl;}

// now continue with rest of program

There are two subtleties here that we will not fully explain

• the object e is a reference to an exception

• the what() function retrieves “Access violation”

Page 10: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 10

What this means to a client

Any code that

• calls a function that might throw an exception

• calls a function that calls a function that might throw an exception

• etc.

• should be wrapped in try-catch blocks

• we try to execute the code in the try-block

• if problems arise we let the catch-block handle it

This passes the responsibility for dealing with the error condition back to the client rather where it belongs

Do not to overuse this feature!

Page 11: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 11

Some words of caution about exceptions

Note: If a function can reasonably handle the error condition itself then it should do so. An exception should be thrown only in the case where the function cannot be expected to handle the situation.

Note: The fact that a function throws an exception is not an excuse for the client to write sloppy code. Remember that an exception should be thrown only when something exceptional occurs.

Note: do not throw exceptions to “bail out” from situations that you as a programmer have difficulty resolving – for example, bailing out from a recursive call because you can’t think of any other way to do it gracefully!

Page 12: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 12

Example of a use of exceptions (1)

Suppose the employee has two data members

• name – to represent the employee’s last name

• employeeNum - to represent the employee numberclass employee{ string name;

int employeeNum; };

Now suppose we want to write a function to read an employee from a file

We can run into two problems when we use the function:

• we hit the end of file so there is no more data to read

• the data in the file is not a valid employee number

Page 13: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 13

Example of a use of exceptions (2)

The last situation will occur if the file contains the following data, for example:

Jones 3542Wong 4214Smith - 5434Ng 6785

• one of these situations is expected (the end of file)

• and the other (invalid format) is not

• we handle them accordingly

• a return value for end-of-file

• an exception for invalid data

Page 14: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 14

Example of a use of exceptions (3)

bool readEmployee( ifstream& inStream, employee& next ){ inStream >> next.name; if( inStream.eof() ) return false; inStream >> next.employeeNum; if( inStream.fail() ) throw BadDataError();

return true;}

• the end-of-file is expected at some point

• we return a bool and let the client check the return value

• finding badly formatted data in the file is not expected

• we handle this situation by throwing an exception

Page 15: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 15

Some of the fine details

We can have more than one catch block

• this allow us to catch different types of exceptions

We catch any type of exception

try{ // do something that might throw an exception

}catch( AccessViolation& excep ){ // do this if AccessViolation

}catch( exception& excep ){ // do this if some other exception class}catch( ... ){ // do this for any other type that is thrown}

Page 16: CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from

CPSC 252 Exception Handling Page 16

Which catch block handles the exception?

If an exception is thrown from the try block, it is handled by the first catch block that can accept it based on its type

• in the previous example, if the exception that gets thrown is a AccessViolation the exception is handled by the first catch block (and only that block)

• if the exception that gets thrown cannot be handled by the first block it is tested against subsequent catch blocks

• if it cannot be handled by any of them, it is handled by the catch-all block.

• it is important to order catch blocks so that earlier blocks handle the more specific exceptions

• the catch-all block, if there is one, must always go last