Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Chapter 17 Templates and Exceptions Dale/Weems/Headington.

Similar presentations


Presentation on theme: "1 Chapter 17 Templates and Exceptions Dale/Weems/Headington."— Presentation transcript:

1 1 Chapter 17 Templates and Exceptions Dale/Weems/Headington

2 2 Chapter 17 Topics l Polymorphism l C++ Function Templates l Instantiating a Function Templates l User-defined Specializations l C++ Class Templates l Instantiating Class Templates l Function Definitions for Members of a Template Class l Exception Classes, Throwing an Exception l Exception Handlers

3 3 Polymorphism l A polymorphic Operation is an operation that has multiple meanings depending on the type of the object to which it is bound at run time.

4 4 Class Complex: Specification class complex { private: double Real, Im; public: complex (double R=0.0, double I=0.0); complex negate (void);// Negation complex add(const complex & Y);// Addition complex sub(const complex & Y);// Subtraction bool isEqual (const complex & Y) const ;// equality complex mult(const double& c, const complex& X); void output(istream& istr, complex& X); void input(ostream& ostr, const complex& X); };

5 5 Operator Overloading l Only C++ built-in operators can be overloaded l Overloaded operator obeys the precedence, associativity, and number of operands dictated by the built-in operator l When an operator is overloaded as a member function, the object associated with the operator is the left-most operand example: X + Y X.operator + (Y) => left-most operand must be an object of the class of which the operator is a member. If that is not the case, instead of using a member operator use a friend operator.

6 6 Complex ADT l Multiplication of a Complex by a Scalar c * X = (c * X.Real, c * X.Im) l Note: In C++, c * X would be translated to c.operator * (X) l The left-most operand of an overloaded operator must be an object of the class being defined. l => can not overload the * for complex scalar multiplication l Solution: use a friend function

7 7 Overloading Operators l Stream I/O operators complex X, Y; cin >> X;// Left-most operand is Not an object cin >> X >> Y;// of type complex cout << “Here is a complex number” << X; cout << X << Y << endl;

8 8 Class Complex: Specification class complex { private: double Real, Im; public: complex (double R=0.0, double I=0.0); complex operator - (void);// Negation complex operator +(const complex & Y);// Addition complex operator - (const complex & Y);// Subtraction bool operator == (const complex & Y) const ;// equality friend complex operator * (const double& c, const complex& X); friend istream& operator >> (istream& istr, complex& X); friend ostream& operator << (ostream& ostr, const complex& X); };

9 9 Class Complex: Implementation complex:: complex(double R, double I) { // The Constructor Real = R; Im = I; } complex complex:: operator - (void) { // returns the value complex(-Real, -Im) return complex( -Real, - Im ); } complex complex::operator + (const complex& Y) { // returns the value complex(Real + Y.Real, Im + Y.Im) return complex( Real + Y.Real, Im + Y.Im ); } complex complex::operator - (const complex& Y) { // returns the value complex( Real - Y.Real, Im - Y.Im ) return complex( Real - X.Real, Im - X.Im ); }

10 10 Friend Functions/Operators complex operator * (const double& c, const complex& X) { return complex(c* X. Real, c*X. Im); } l A friend function is a function defined outside of the class scope. Note: there is no scope resolution l It is a friend function because in the class specification the keyword “friend” is used in the prototype l A friend function of a class has access to the private members of the class l Inside the function definition, the dot operator is required to access the class data members. l Note that for a binary operation, two arguments are required

11 11 Overloaded Stream Input Operator >> istream& operator >> (istream& istr, complex& X) { // paramter istr represents an input stream such cin // The two parameters are passed by reference because they are // modified by the function // The function returns a reference to an istream object so that input // operations can be chained istr >> X.Real >> X.Im ; return istr ; } Example:complex A, B ; cin >> A >> B;

12 12 Overloaded Stream Output Operator << ostream& operator << (ostream& ostr, const complex& X) { // The second parameter is passed by reference; but it is read-only ostr << X.Real << X.Im ; return ostr ; } l Example: complex A, B; …… cout << A << B;

13 13 Function Overloading 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.

14 14 Example of Function Overloading void Print( int n ) { cout << "***Debug" << endl; cout << "Value is " << n << endl; } void Print( char ch ) { cout << "***Debug" << endl; cout << "Value is " << ch << endl; } void Print( float x ) { …. } Print(someInt); Print(someChar); Print(someFloat); To output the traced values, we insert:

15 15 Function Template A C++ language construct that allows the compiler to generate multiple versions of a function by allowing parameterized data types. Template FunctionDefinition FunctionTemplate TemplateParamDeclaration class Identifier typename

16 16 Example of a Function Template template void Print( SomeType val ) { cout << "***Debug" << endl; cout << "Value is " << val << endl; } Print (sum); Print (initial); Print (angle); To output the traced values, we insert: Template parameter Template argument

17 17 Instantiating a Function Template When the compiler instantiates a template, it substitutes the template argument for the template parameter throughout the function template. Function (FunctionArgList) TemplateFunction Call

18 18 User-Defined Specializations Example that demonstrates use of template template<> void Print( string vName, // Name of the variable StatusType val ) // Value of the variable { cout << "***Debug" << endl; cout << "Value of " << vName << " = "; switch (val)

19 19 Example, continued. { case OK : cout << "OK"; break; case OUT_OF_STOCK : cout << "OUT_OF_STOCK"; break; case BACK_ORDERED : cout << "BACK_ORDERED"; break; default : cout << "Invalid value"; } cout << endl; }

20 20 Organization of Program Code Three possibilities: 1.Template definitions at the beginning of program file, prior to main function. 2.Function prototypes first, then the main function, then the template definitions. 3.Template definition in the header file, use #include to insert that file into the program

21 21 What is a Generic Data Type? It is a type for which the operations are defined but the data types of the items being manipulated are not.

22 22 What is a Class Template? It is a C++ language construct that allows the compiler to generate multiple versions of a class by allowing parameterized data types

23 23 Example of a Class Template template class GList { 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]; }; Template parameter

24 24 Instantiating a Class Template // Client code GList list1; GList list2; GList list3; list1.Insert(356); list2.Insert(84.375); list3.Insert("Muffler bolt"); To create lists of different data types GList_int list1; GList_float list2; GList_string list3; template argument Compiler generates 3 distinct class types

25 25 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.

26 26 Writing Function Templates template void GList ::Insert( /* in */ ItemType item ) { data[length] = item; length++; }

27 27 Organization of Program Code A compiler must know the argument to the template in order to generate a function template, and this argument is located in the client code. l General Solution: Compile client code and the class member functions simultaneously.

28 28 Warning! Are you using an IDE (integrated development environment) where the editor, compiler, and linker are bundled into one application? Remember: The compiler must know the template argument. Specifying two files separates the compiler from the template argument. Provide the compiler with only one chunk of code: the file with the template arguments.

29 29 An Exception is… An unusual, often unpredictable event, detectable by software or hardware, that requires special processing; also, in C++, a variable or class object that represents an exceptional event. An exception handler is a section of program code that is executed when a particular exception occurs.

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

31 31 The try-catch Statement try Block catch (FormalParameter) Block catch (FormalParameter) TryCatchStatement How one part of the program catches and processes the exception that another part of the program throws. FormalParameter DataType VariableName …

32 32 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 ) {

33 33 try-catch Continued cout << s << endl; // Prints "Invalid customer age" // More statements to handle an age error } catch ( SalaryError ) { // Statements to handle a salary error }

34 34 Execution of try-catch No statements throw an exception Statement following entire try-catch statement A statement throws an exception Exception Handler Statements to deal with exception are executed Control moves directly to exception handler

35 35 Selecting an Exception Handler The computer: Examines data types of the formal parameters in exception handlers Searches in a “north-to-south” order Selects first formal parameter whose data type matches that of the thrown exception Ellipse parameters are a “wild card” and catch all. Place the “catch all” handler last.

36 36 More on Selecting Exception Handlers The parameter’s name is needed only if statements in the body of the exception handler use that variable. It is a good idea to use only user-defined classes (and structs) as exception types, one type per exception descriptive identifiers

37 37 Nonlocal Exception Handlers It is more common for the throw to occur inside a function that is called from within a try- clause than for the throw to be located within the try-catch statement

38 38 Throwing an Exception to be Caught by the Calling Code void Func4() { if ( error ) throw ErrType(); } Normal return void Func3() { try { Func4(); } catch ( ErrType ) { } } Function call Return from thrown exception

39 39 No ErrType handler ErrType handler No ErrType handler throw ErrType(); Cal l Immediate return Immediate return Immediate return Func1 No ErrType handler throw ErrType(); Call Immediate return Immediate return Immediate return Program terminates immediately Func2 Func3 Func4 main Immediate return Function Func1 has a handler for ErrTypeNo function has a handler for ErrType Func1 Func2 Func3 Func4 Passing an Exception up the Chain of Function Calls

40 40 Re-Throwing an Exception l The throw expression is optional. throw; l Re-throwing an exception in C++ allows partial exception handling.

41 41 Standard Exceptions l Exceptions Thrown by the Language l new, dynamic_cast, typeid, exception specification l Exceptions Thrown by Standard Library Routines l Facilities inherited from the C language l Facilities designed specifically for C++

42 42 Dividing by ZERO Apply what you know: int Quotient( /* in */ int numer, // The numerator /* in */ int denom ) // The denominator { if (denom != 0) return numer / denom; else // What to do?? }

43 43 A Solution // quotient.cpp -- Quotient program #include #include using namespace std; int Quotient( int, int ); class DivByZero // Exception class {}; int main() { int numer; // Numerator int denom; // Denominator

44 44 cout << "Enter numerator and denominator: "; cin >> numer >> denom; while (cin) { try { cout << "Their quotient: " << Quotient(numer, denom) << endl; } catch ( DivByZero ) { cout << "*** Denominator can't be 0" << endl; } cout << "Enter numerator and denominator: "; cin >> numer >> denom; } return 0; }

45 45 int Quotient( /* in */ int numer, // The numerator /* in */ int denom ) // The denominator { if (denom == 0) throw DivByZero(); return numer / denom; }


Download ppt "1 Chapter 17 Templates and Exceptions Dale/Weems/Headington."

Similar presentations


Ads by Google