You are on page 1of 47

Introduction to C++ Templates and Exceptions

C++ Function Templates C++ Class Templates Exception and Exception Handler

C++ Function Templates

Approaches for functions that implement identical tasks for different data types

Nave Approach

Function Overloading Function Template Instantiating a Function Templates

Approach 1: Nave Approach

create unique functions with unique names for each combination of data types

difficult to keeping track of multiple function names lead to programming errors

Example
void PrintInt( int n ) { cout << "***Debug" << endl; cout << "Value is " << n << endl; } void PrintChar( char ch ) { cout << "***Debug" << endl; cout << "Value is " << ch << endl; } void PrintFloat( float x ) To output the traced values, we insert: { PrintInt(sum); } void PrintDouble( double d ) PrintChar(initial); { PrintFloat(angle); }

Approach 2:Function Overloading (Review)

The use of the same name for different C++ functions, distinguished from each other by their parameter lists
Eliminates need to come up with many different names for identical tasks. Reduces the chance of unexpected results caused by using the wrong function name.

Example of Function Overloading


void Print( { cout << cout << } void Print( { cout << cout << } void Print( { } int n )

"***Debug" << endl; "Value is " << n << endl;


char ch )

"***Debug" << endl; "Value is " << ch << endl;


float x )
To output the traced values, we insert:

Print(someInt); Print(someChar); Print(someFloat);

Approach 3: Function Template


A C++ language construct that allows the compiler to generate multiple versions of a function by allowing parameterized data types. FunctionTemplate Template < TemplateParamList > FunctionDefinition TemplateParamDeclaration: placeholder class typeIdentifier typename variableIdentifier

Example of a Function Template


template<class SomeType>
Template parameter (class, user defined type, built-in types)

void Print( SomeType val ) { cout << "***Debug" << endl; cout << "Value is " << val << endl; }

Template argument

To output the traced values, we insert:

Print<int>(sum); Print<char>(initial); Print<float>(angle);

Instantiating a Function Template

When the compiler instantiates a template, it substitutes the template argument for the template parameter throughout the function template.

TemplateFunction Call Function < TemplateArgList > (FunctionArgList)

Summary of Three Approaches


Nave Approach Different Function Definitions Different Function Names Function Overloading Different Function Definitions Same Function Name

Template Functions One Function Definition (a function template) Compiler Generates Individual Functions

Class Template
A C++ language construct that allows the compiler to generate multiple versions of a class by allowing parameterized data types. Class Template Template < TemplateParamList > ClassDefinition TemplateParamDeclaration: placeholder class typeIdentifier typename variableIdentifier

Example of a Class Template


template<class ItemType> class GList Template { parameter public: bool IsEmpty() const; bool IsFull() const; int Length() const; void Insert( /* in */ ItemType item ); void Delete( /* in */ ItemType item ); bool IsPresent( /* in */ ItemType item ) const; void SelSort(); void Print() const; GList(); // Constructor private: int length; ItemType data[MAX_LENGTH]; };

Instantiating a Class Template

Class template arguments must be explicit. The compiler generates distinct class types called template classes or generated classes. When instantiating a template, a compiler substitutes the template argument for the template parameter throughout the class template.

Instantiating a Class Template


To create lists of different data types
// Client code GList<int> list1; GList<float> list2; GList<string> list3; list1.Insert(356); list2.Insert(84.375); list3.Insert("Muffler bolt"); template argument

Compiler generates 3 distinct class types


GList_int list1; GList_float list2; GList_string list3;

Substitution Example
class GList_int { public:

int
int

void Insert( /* in */ ItemType item ); void Delete( /* in */ ItemType item );

bool IsPresent( /* in */ ItemType item ) const; private: int length; ItemType data[MAX_LENGTH]; }; int int

Function Definitions for Members of a Template Class


template<class ItemType> void GList<ItemType>::Insert( /* in */ ItemType item ) { data[length] = item; length++; }

//after substitution of float


void GList<float>::Insert( /* in */ float item ) { data[length] = item;

length++;
}

Another Template Example: passing two parameters


template <class T, int size> class Stack {... non-type parameter };

Stack<int,128> mystack;

Exception

An exception is a unusual, often unpredictable event, detectable by software or hardware, that requires special processing occurring at runtime In C++, a variable or class object that represents an exceptional event.

Errors can be dealt with at place error occurs


Easy to see if proper error checking implemented Harder to read application itself and see how code works Makes clear, robust, fault-tolerant programs C++ removes error handling code from "main line" of program new not allocating memory Out of bounds array subscript Division by zero Invalid function parameters

Exception handling

Common failures

Exception handling - catch errors before they occur

Deals with synchronous errors (i.E., Divide by zero) Does not deal with asynchronous errors - disk I/O completions, mouse clicks - use interrupt processing Used when system can recover from error Exception handler - recovery procedure Typically used when error dealt with in different place than where it occurred Useful when program cannot recover but must shut down cleanly

Exception handling should not be used for program control

Not optimized, can harm program performance

Exception handling improves fault-tolerance


Easier to write error-processing code Specify what type of exceptions are to be caught

Most programs support only single threads

Techniques in this chapter apply for multithreaded OS as well (windows NT, OS/2, some UNIX)

Exception handling another way to return control from a function or block of code

Handling Exception

If without handling, Program crashes Falls into unknown state An exception handler is a section of program code that is designed to execute when a particular exception occurs Resolve the exception Lead to known state, such as exiting the program

Standard Exceptions

Exceptions Thrown by the Language

new

Exceptions Thrown by Standard Library Routines Exceptions Thrown by user code, using throw statement

When Exception Handling Should Be Used

Error handling should be used for


Processing exceptional situations Processing exceptions for components that cannot handle them directly Processing exceptions for widely used components (libraries, classes, functions) that should not process their own exceptions Large projects that require uniform error processing

Basics of C++ Exception Handling: try, throw, catch

A function can throw an exception object if it detects an error

Object typically a character string (error message) or class object If exception handler exists, exception caught and handled Otherwise, program terminates

Basics of C++ Exception Handling: try, throw, catch (II)

Format
Enclose code that may have an error in try block Follow with one or more catch blocks

Each catch block has an exception handler

If exception occurs and matches parameter in catch block, code in catch block executed If no exception thrown, exception handlers skipped and control resumes after catch blocks throw point - place where exception occurred

Control cannot return to throw point

throw - indicates an exception has occurred

Usually has one operand (sometimes zero) of any type


If operand an object, called an exception object Conditional expression can be thrown

Code referenced in a try block can throw an exception

Exception caught by closest exception handler Control exits current try block and goes to catch handler (if it exists) Example (inside function definition)
if ( denominator == 0 )
throw DivideByZeroException(); Throws a dividebyzeroexception object

The throw Statement


Throw: to signal the fact that an exception has occurred; also called raise
ThrowStatement
throw Expression

Exception handlers are in catch blocks


Format: catch( exceptionType parameterName){ exception handling code } Caught if argument type matches throw type If not caught then terminate called which (by default) calls abort

Example:

catch ( DivideByZeroException ex) { cout << "Exception occurred: " << ex.what() <<'\n' }

Catches exceptions of type DivideByZeroException

Catch all exceptions


catch(...) - catches all exceptions
You do not know what type of exception occurred There is no parameter name - cannot reference the object

If no handler matches thrown object


Searches next enclosing try block


If none found, terminate called

If found, control resumes after last catch block If several handlers match thrown object, first one found is executed

catch parameter matches thrown object when

They are of the same type


Exact match required - no promotions/conversions allowed

The catch parameter is a public base class of the thrown object The catch parameter is a base-class pointer/ reference type and the thrown object is a derived-class pointer/ reference type The catch handler is catch( ... ) Thrown const objects have const in the parameter type

Unreleased resources

Resources may have been allocated when exception thrown catch handler should delete space allocated by new and close any opened files

catch handlers can throw exceptions

Exceptions can only be processed by outer try blocks

The try-catch Statement


How one part of the program catches and processes the exception that another part of the program throws. TryCatchStatement try Block catch (FormalParameter) Block catch (FormalParameter)

FormalParameter
DataType VariableName

Example of a try-catch Statement


try { // Statements that process personnel data and may throw // exceptions of type int, string, and SalaryError } catch ( int ) { // Statements to handle an int exception } catch ( string s ) { cout << s << endl; // Prints "Invalid customer age" // More statements to handle an age error } catch ( SalaryError ) { // Statements to handle a salary error }

Execution of try-catch
A statement throws an exception
Control moves directly to exception handler

No statements throw an exception

Exception Handler

Statements to deal with exception are executed

Statement following entire try-catch statement

Throwing an Exception to be Caught by the Calling Code


void Func3() {
try { Func4(); } catch ( ErrType ) { } }
void Func4() { if ( error ) throw ErrType(); } Return from thrown exception

Function call

Normal return

Practice: Dividing by ZERO


Apply what you know:
int Quotient(int numer, int denom ) { if (denom != 0) return numer / denom; else //What to do?? do sth. to avoid program //crash } // The numerator // The denominator

A Solution
int Quotient(int numer, int denom ) { if (denom == 0) throw DivByZero(); // The numerator // The denominator

//throw exception of class DivByZero


return numer / denom; }

A Solution
// quotient.cpp -- Quotient program #include<iostream.h> #include <string.h> int Quotient( int, int ); class DivByZero {}; // Exception class while(cin) { try { cout << "Their quotient: " << Quotient(numer,denom) <<endl; } catch ( DivByZero )//exception handler { cout<<Denominator can't be 0"<< endl; } // read in numerator and denominator

int main()
{ int numer; // Numerator int denom; // Denominator //read in numerator and denominator

} return 0; }

Take Home Message

Templates are mechanisms for generating functions and classes on type parameters. We can design a single class or function that operates on data of many types
function templates class templates

An exception is a unusual, often unpredictable event that requires special processing occurring at runtime
throw try-catch

Rethrowing exceptions

Used when an exception handler cannot process an exception Rethrow exception with the statement:
throw; No arguments If no exception thrown in first place, calls terminate

Handler can always rethrow exception, even if it performed some processing Rethrown exception detected by next enclosing try block

1 2 3 4 5 6 7 8 9

// Fig. 23.2: fig23_02.cpp // Demonstration of rethrowing an exception. #include <iostream>

using std::cout; using std::endl;

#include <exception>

10 using std::exception; 11 12 void throwException() 13 { 14 15 16 17 18 19 } catch( exception e ) // Throw an exception and immediately catch it. try { cout << "Function throwException\n"; throw exception();

1. Load header

// generate exception

20
21

1.1 Function prototype

cout << "Exception handled in function throwException\n";

22 23 24 25 26 } 27 }

throw;

// rethrow exception for further processing

cout << "This also should not print\n";

28 int main() 29 { 30 try {

31
32 33 34 35 36 37 38 39 40 41 42 } } }

throwException();
cout << "This should not print\n";

catch ( exception e ) { cout << "Exception handled in main\n";

cout << "Program control continues after catch in main" << endl; return 0;

2. Function call
3. Output

Function throwException Exception handled in function throwException Exception handled in main Program control continues after catch in main

Exception specification (throw list)

Lists exceptions that can be thrown by a function

Example:

int g( double h ) throw ( a, b, c ) { // function body }


Function can throw listed exceptions or derived types If other type thrown, function unexpected called throw() (i.e., no throw list) states that function will not throw any exceptions In reality, function can still throw exceptions, but calls unexpected (more later) If no throw list specified, function can throw any exception

Function unexpected

Calls the function specified with set_unexpected Default: terminate Calls function specified with set_terminate Default: abort Prototypes in <exception> Take pointers to functions (i.E., Function name) Function must return void and take no arguments Returns pointer to last function called by terminate or unexpected

Function terminate

set_terminate and set_unexpected


Uncaught Exception

Function-call stack unwound when exception thrown and not caught in a particular scope
Tries

to catch exception in next outer try/catch

block Function in which exception was not caught terminates Local variables destroyed Control returns to place where function was called If control returns to a try block, attempt made to catch exception Otherwise, further unwinds stack If exception not caught, terminate called

Constructors, Destructors and Exception Handling

What to do with an error in a constructor?

A constructor cannot return a value - how do we let the outside world know of an error?
Keep defective object and hope someone tests it Set some variable outside constructor

A thrown exception can tell outside world about a failed constructor catch handler must have a copy constructor for thrown object

You might also like