Chapter 16 Exceptions and Templates
16.1 Exceptions
Concept:
- Exceptions are used to signal errors or other unexpected events that happen while a program is running.
- Simple error testing can be done with
ifstatements, but this approach is unreliable for functions that need to return a value, as the error-indicating return value (like 0) might also be a valid result.
Throwing an Exception
- Exceptions provide a more robust way to handle complex errors. An exception is an object or value that signals an error.
- When an error occurs, an exception is “thrown” using the
throwkeyword.
double divide(int numerator, int denominator)
{
if (denominator == 0)
throw "ERROR: Cannot divide by zero.\n";
else
return static_cast<double>(numerator) / denominator;
}Throwing an Exception
- The line with the
throwstatement is called the throw point. - When an exception is thrown, the function aborts and control is passed to an exception handler.
Handling an Exception
- To handle an exception, you use a
try/catchconstruct. - The
tryblock contains code that might throw an exception. - The
catchblock is the exception handler; it immediately follows thetryblock and contains code to handle the exception.
try
{
quotient = divide(num1, num2);
cout << "The quotient is " << quotient << endl;
}
catch (string exceptionString)
{
cout << exceptionString;
}Handling an Exception
- The
catchblock has an exception parameter that specifies the data type of the exception it can handle. - The following program demonstrates the complete
throw,try, andcatchmechanism.
🗊 Program 16-1
#include <iostream>
#include <string>
using namespace std;
double divide(int, int);
int main()
{
int num1, num2;
double quotient;
cout << "Enter two numbers: ";
cin >> num1 >> num2;
try
{
quotient = divide(num1, num2);
cout << "The quotient is " << quotient << endl;
}
catch (string exceptionString)
{
cout << exceptionString;
}
cout << "End of the program.\n";
return 0;
}
double divide(int numerator, int denominator)
{
if (denominator == 0)
{
string exceptionString = "ERROR: Cannot divide by zero.\n";
throw exceptionString;
}
return static_cast<double>(numerator) / denominator;
}💻 Program Output
💻 Program Output
When an exception is thrown, the program jumps from the
throwpoint to thecatchblock. After thecatchblock finishes, execution resumes at the statement immediately following thetry/catchconstruct.If no exception is thrown in the
tryblock, thecatchblock is skipped entirely.
What if an Exception Is Not Caught?
- If an exception is thrown outside of a
tryblock, or if there is nocatchblock with a matching data type, the exception will go uncaught. - An uncaught exception will cause the program to abort.
Object-Oriented Exception Handling with Classes
- A common object-oriented approach is to define special classes to represent exceptions.
- The
Rectangleclass below is modified to throw an exception if a negative value is provided for width or length.
Contents of Rectangle.h (Version 1)
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle
{
private:
double width;
double length;
public:
class NegativeSize
{ };
Rectangle()
{ width = 0.0; length = 0.0; }
void setWidth(double);
void setLength(double);
double getWidth() const
{ return width; }
double getLength() const
{ return length; }
double getArea() const
{ return width * length; }
};
#endif- An empty class,
NegativeSize, is declared. Its name is used to identify the type of error.
Contents of Rectangle.cpp (Version 1)
- The
setWidthandsetLengthfunctions throw an instance of theNegativeSizeclass if their argument is negative. - Code that uses the
Rectangleclass can then use acatchblock to handleNegativeSizeexceptions.
🗊 Program 16-2
#include <iostream>
#include "Rectangle.h"
using namespace std;
int main()
{
double width;
double length;
Rectangle myRectangle;
cout << "Enter the rectangle's width: ";
cin >> width;
cout << "Enter the rectangle's length: ";
cin >> length;
try
{
myRectangle.setWidth(width);
myRectangle.setLength(length);
cout << "The area of the rectangle is "
<< myRectangle.getArea() << endl;
}
catch (Rectangle::NegativeSize)
{
cout << "Error: A negative value was entered.\n";
}
cout << "End of the program.\n";
return 0;
}💻 Program Output
💻 Program Output
- The
catchstatement specifies the type of exception it handles (Rectangle::NegativeSize). Since the exception class is nested, its name must be qualified with the scope resolution operator.
Multiple Exceptions
- A program can be designed to handle multiple types of errors.
- This requires defining a different exception type for each error and using a separate
catchblock for each exception type. - The
Rectangleclass can be modified to throw aNegativeWidthexception for an invalid width and aNegativeLengthexception for an invalid length.
Contents of Rectangle.h (Version 2)
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle
{
private:
double width;
double length;
public:
class NegativeWidth
{ };
class NegativeLength
{ };
Rectangle()
{ width = 0.0; length = 0.0; }
void setWidth(double);
void setLength(double);
double getWidth() const
{ return width; }
double getLength() const
{ return length; }
double getArea() const
{ return width * length; }
};
#endifContents of Rectangle.cpp (Version 2)
- When an exception is thrown, C++ searches for a
catchblock that matches the exception’s type.
🗊 Program 16-3
#include <iostream>
#include "Rectangle.h"
using namespace std;
int main()
{
double width;
double length;
Rectangle myRectangle;
cout << "Enter the rectangle's width: ";
cin >> width;
cout << "Enter the rectangle's length: ";
cin >> length;
try
{
myRectangle.setWidth(width);
myRectangle.setLength(length);
cout << "The area of the rectangle is "
<< myRectangle.getArea() << endl;
}
catch (Rectangle::NegativeWidth)
{
cout << "Error: A negative value was given "
<< "for the rectangle's width.\n";
}
catch (Rectangle::NegativeLength)
{
cout << "Error: A negative value was given "
<< "for the rectangle's length.\n";
}
cout << "End of the program.\n";
return 0;
}💻 Program Output
💻 Program Output
💻 Program Output
Using Exception Handlers to Recover from Errors
- Exception handlers can be used to recover from errors, for example, by prompting the user to re-enter valid data inside a loop.
🗊 Program 16-4
#include <iostream>
#include "Rectangle.h"
using namespace std;
int main()
{
double width;
double length;
bool tryAgain = true;
Rectangle myRectangle;
cout << "Enter the rectangle's width: ";
cin >> width;
while (tryAgain)
{
try
{
myRectangle.setWidth(width);
tryAgain = false;
}
catch (Rectangle::NegativeWidth)
{
cout << "Please enter a nonnegative value: ";
cin >> width;
}
}
cout << "Enter the rectangle's length: ";
cin >> length;
tryAgain = true;
while (tryAgain)
{
try
{
myRectangle.setLength(length);
tryAgain = false;
}
catch (Rectangle::NegativeLength)
{
cout << "Please enter a nonnegative value: ";
cin >> length;
}
}
cout << "The rectangle's area is "
<< myRectangle.getArea() << endl;
return 0;
}💻 Program Output
Extracting Data from the Exception Class
- An exception class can be designed with member variables and functions to pass data back to the exception handler.
- To do this, the exception class needs a constructor to store the data and an accessor function to retrieve it.
- When throwing the exception, an argument is passed to the exception class’s constructor.
throw NegativeWidth(w);- The
catchblock then defines a parameter object to receive the exception object and call its member functions.
catch (Rectangle::NegativeWidth e)
{
cout << "Error: " << e.getValue() << " is invalid.\n";
}Contents of Rectangle.h (Version 3)
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle
{
private:
double width;
double length;
public:
class NegativeWidth
{
private:
double value;
public:
NegativeWidth(double val)
{ value = val; }
double getValue() const
{ return value; }
};
class NegativeLength
{
private:
double value;
public:
NegativeLength(double val)
{ value = val; }
double getValue() const
{ return value; }
};
Rectangle()
{ width = 0.0; length = 0.0; }
void setWidth(double);
void setLength(double);
double getWidth() const
{ return width; }
double getLength() const
{ return length; }
double getArea() const
{ return width * length; }
};
#endifContents of Rectangle.cpp (Version 3)
🗊 Program 16-5
#include <iostream>
#include "Rectangle.h"
using namespace std;
int main()
{
double width;
double length;
Rectangle myRectangle;
cout << "Enter the rectangle's width: ";
cin >> width;
cout << "Enter the rectangle's length: ";
cin >> length;
try
{
myRectangle.setWidth(width);
myRectangle.setLength(length);
cout << "The area of the rectangle is "
<< myRectangle.getArea() << endl;
}
catch (Rectangle::NegativeWidth e)
{
cout << "Error: " << e.getValue()
<< " is an invalid value for the"
<< " rectangle's width.\n";
}
catch (Rectangle::NegativeLength e)
{
cout << "Error: " << e.getValue()
<< " is an invalid value for the"
<< " rectangle's length.\n";
}
cout << "End of the program.\n";
return 0;
}💻 Program Output
💻 Program Output
Unwinding the Stack
- When an exception is thrown, the function containing the
throwstatement immediately terminates. - If the function was called by another function, the calling function also terminates, and this process continues up the chain of function calls until a
tryblock is found. This process is known as unwinding the stack. - During stack unwinding, the destructors of any local objects created in the terminating functions are called.
Rethrowing an Exception
- It’s possible for an inner
catchblock to handle an exception and then rethrow it to an outercatchblock. - This is done using a
throwstatement with no arguments inside the innercatchblock.
catch(exception1)
{
throw;
}Handling the bad_alloc Exception
- The
newoperator throws abad_allocexception when it fails to allocate memory. - To handle this, include the
<new>header file and place thenewoperator call inside atryblock. - A
catchblock can then be written to handle thebad_allocexception.
🗊 Program 16-6
Checkpoint
16.1 What is the difference between a try block and a catch block?
16.2 What happens if an exception is thrown, but not caught?
16.3 If multiple exceptions can be thrown, how does the catch block know which exception to catch?
16.4 After the catch block has handled the exception, where does program execution resume?
16.5 How can an exception pass data back to the exception handler?
16.2 Function Templates
Concept:
- A function template is a generic function “mold” that can work with any data type.
- The programmer defines the function’s logic using generic type parameters instead of actual data types.
- The compiler generates a specific version of the function (a template function) based on the data types used in a function call.
Introduction
- Function templates are more convenient than overloaded functions when the same logic applies to different data types.
- Instead of writing multiple versions of a function, you write a single template.
- A function template uses a type parameter to represent a generic data type.
template <class T>
T square(T number)
{
return number * number;
}Writing a Function Template
- The template begins with a template prefix:
template <class T>. Tis the type parameter, which stands for a data type that will be specified when the function is called.- The compiler automatically generates the appropriate function code based on the argument types. For example,
square(4)generates anintversion, whilesquare(6.2)generates adoubleversion.
🗊 Program 16-7
#include <iostream>
#include <iomanip>
using namespace std;
template <class T>
T square(T number)
{
return number * number;
}
int main()
{
int userInt;
double userDouble;
cout << setprecision(5);
cout << "Enter an integer and a floating-point value: ";
cin >> userInt >> userDouble;
cout << "Here are their squares: ";
cout << square(userInt) << " and "
<< square(userDouble) << endl;
return 0;
}💻 Program Output
Note:
- Every type parameter defined in a template’s prefix must be used in the function’s parameter list.
A template itself doesn’t use memory; a function instance is only created when the compiler encounters a call to it.
The template definition must appear before any calls to the function, so it’s often placed at the top of a file or in a header file.
🗊 Program 16-8
#include <iostream>
using namespace std;
template <class T>
void swapVars(T &var1, T &var2)
{
T temp;
temp = var1;
var1 = var2;
var2 = temp;
}
int main()
{
char firstChar, secondChar;
int firstInt, secondInt;
double firstDouble, secondDouble;
cout << "Enter two characters: ";
cin >> firstChar >> secondChar;
swapVars(firstChar, secondChar);
cout << firstChar << " " << secondChar << endl;
cout << "Enter two integers: ";
cin >> firstInt >> secondInt;
swapVars(firstInt, secondInt);
cout << firstInt << " " << secondInt << endl;
cout << "Enter two floating-point numbers: ";
cin >> firstDouble >> secondDouble;
swapVars(firstDouble, secondDouble);
cout << firstDouble << " " << secondDouble << endl;
return 0;
}💻 Program Output
Using Operators in Function Templates
- If you pass a class object to a function template, the class must support all operations (like
*,>,==) that the template performs on it. This may require operator overloading.
Function Templates with Multiple Types
- A function template can have more than one generic type parameter. Each must be listed in the template prefix.
- This allows the template to accept arguments of different types.
🗊 Program 16-9
#include <iostream>
using namespace std;
template <class T1, class T2>
int largest(const T1 &var1, T2 &var2)
{
if (sizeof(var1) > sizeof(var2))
return sizeof(var1);
else
return sizeof(var2);
}
int main()
{
int i = 0;
char c = ' ';
float f = 0.0;
double d = 0.0;
cout << "Comparing an int and a double, the largest\n"
<< "of the two is " << largest(i, d) << " bytes.\n";
cout << "Comparing a char and a float, the largest\n"
<< "of the two is " << largest(c, f) << " bytes.\n";
return 0;
}💻 Program Output
Note:
- Each type parameter in the template prefix must be used in the template’s definition.
Overloading with Function Templates
- Function templates can be overloaded as long as they have different parameter lists.
- A program can also have both a regular function and a template version of a function with the same name, as long as their parameter lists differ.
🗊 Program 16-10
#include <iostream>
using namespace std;
template <class T>
T sum(T val1, T val2)
{
return val1 + val2;
}
template <class T>
T sum(T val1, T val2, T val3)
{
return val1 + val2 + val3;
}
int main()
{
double num1, num2, num3;
cout << "Enter two values: ";
cin >> num1 >> num2;
cout << "Their sum is " << sum(num1, num2) << endl;
cout << "Enter three values: ";
cin >> num1 >> num2 >> num3;
cout << "Their sum is " << sum(num1, num2, num3) << endl;
return 0;
}💻 Program Output
16.3 Focus on Software Engineering: Where to Start When Defining Templates
- A good strategy for writing a function template is to first write it as a regular function with a specific data type.
- After the regular function is tested and debugged, you can convert it into a template by adding the
templateprefix and replacing the specific data types with the generic type parameter.
Checkpoint
16.6 When does the compiler actually generate code for a function template?
16.7 The following function accepts an
intargument and returns half of its value as adouble:double half(int number) { return number / 2.0; }Write a template that will implement this function to accept an argument of any type.
16.8 What must you be sure of when passing a class object to a function template that uses an operator, such as
*or>?16.9 What is the best method for writing a function template?
16.4 Class Templates
Concept:
- Class templates are used to create generic classes that can work with multiple data types. This avoids duplicating code for classes that have the same logic but handle different types (e.g., an array class for
ints,doubles, etc.).
- A class template is declared by placing a
templateprefix before the class declaration. - Inside the class, the generic type parameter (e.g.,
T) is used in place of a specific data type.
Contents of SimpleVector.h
#ifndef SIMPLEVECTOR_H
#define SIMPLEVECTOR_H
#include <iostream>
#include <new>
#include <cstdlib>
using namespace std;
template <class T>
class SimpleVector
{
private:
T *aptr;
int arraySize;
void memError();
void subError();
public:
SimpleVector()
{ aptr = 0; arraySize = 0;}
SimpleVector(int);
SimpleVector(const SimpleVector &);
~SimpleVector();
int size() const
{ return arraySize; }
T getElementAt(int position);
T &operator[](const int &);
};
template <class T>
SimpleVector<T>::SimpleVector(int s)
{
arraySize = s;
try
{
aptr = new T [s];
}
catch (bad_alloc)
{
memError();
}
for (int count = 0; count < arraySize; count++)
*(aptr + count) = 0;
}
template <class T>
SimpleVector<T>::SimpleVector(const SimpleVector &obj)
{
arraySize = obj.arraySize;
aptr = new T [arraySize];
if (aptr == 0)
memError();
for(int count = 0; count < arraySize; count++)
*(aptr + count) = *(obj.aptr + count);
}
template <class T>
SimpleVector<T>::~SimpleVector()
{
if (arraySize > 0)
delete [] aptr;
}
template <class T>
void SimpleVector<T>::memError()
{
cout << "ERROR:Cannot allocate memory.\n";
exit(EXIT_FAILURE);
}
template <class T>
void SimpleVector<T>::subError()
{
cout << "ERROR: Subscript out of range.\n";
exit(EXIT_FAILURE);
}
template <class T>
T SimpleVector<T>::getElementAt(int sub)
{
if (sub < 0 || sub >= arraySize)
subError();
return aptr[sub];
}
template <class T>
T &SimpleVector<T>::operator[](const int &sub)
{
if (sub < 0 || sub >= arraySize)
subError();
return aptr[sub];
}
#endifNote:
- Members that do not depend on the type parameter, like
arraySize, can still use specific data types likeint.
Defining Objects of the Class Template
- To define an object of a class template, you must specify the data type to be used for the type parameter.
- This is done by writing the data type in angle brackets after the class name.
SimpleVector<int> intTable(10);
SimpleVector<double> doubleTable(10);🗊 Program 16-11
#include <iostream>
#include "SimpleVector.h"
using namespace std;
int main()
{
const int SIZE = 10;
int count;
SimpleVector<int> intTable(SIZE);
SimpleVector<double> doubleTable(SIZE);
for (count = 0; count < SIZE; count++)
{
intTable[count] = (count * 2);
doubleTable[count] = (count * 2.14);
}
cout << "These values are in intTable:\n";
for (count = 0; count < SIZE; count++)
cout << intTable[count] << " ";
cout << endl;
cout << "These values are in doubleTable:\n";
for (count = 0; count < SIZE; count++)
cout << doubleTable[count] << " ";
cout << endl;
cout << "\nAdding 5 to each element of intTable"
<< " and doubleTable.\n";
for (count = 0; count < SIZE; count++)
{
intTable[count] = intTable[count] + 5;
doubleTable[count] = doubleTable[count] + 5.0;
}
cout << "These values are in intTable:\n";
for (count = 0; count < SIZE; count++)
cout << intTable[count] << " ";
cout << endl;
cout << "These values are in doubleTable:\n";
for (count = 0; count < SIZE; count++)
cout << doubleTable[count] << " ";
cout << endl;
cout << "\nIncrementing each element of intTable and"
<< " doubleTable.\n";
for (count = 0; count < SIZE; count++)
{
intTable[count]++;
doubleTable[count]++;
}
cout << "These values are in intTable:\n";
for (count = 0; count < SIZE; count++)
cout << intTable[count] << " ";
cout << endl;
cout << "These values are in doubleTable:\n";
for (count = 0; count < SIZE; count++)
cout << doubleTable[count] << " ";
cout << endl;
return 0;
}💻 Program Output
Class Templates and Inheritance
- A class template can be derived from another class template.
- When specifying the base class, its type parameter must also be included, for example:
class SearchableVector : public SimpleVector<T>.
Contents of SearchableVector.h
#ifndef SEARCHABLEVECTOR_H
#define SEARCHABLEVECTOR_H
#include "SimpleVector.h"
template <class T>
class SearchableVector : public SimpleVector<T>
{
public:
SearchableVector() : SimpleVector<T>()
{ }
SearchableVector(int size) : SimpleVector<T>(size)
{ }
SearchableVector(const SearchableVector &);
int findItem(const T);
};
template <class T>
SearchableVector<T>::SearchableVector(const SearchableVector &obj) :
SimpleVector<T>(obj.size())
{
for(int count = 0; count < this->size(); count++)
this->operator[](count) = obj[count];
}
template <class T>
int SearchableVector<T>::findItem(const T item)
{
for (int count = 0; count <= this->size(); count++)
{
if (getElementAt(count) == item)
return count;
}
return -1;
}
#endif🗊 Program 16-12
#include <iostream>
#include "SearchableVector.h"
using namespace std;
int main()
{
const int SIZE = 10;
int count;
int result;
SearchableVector<int> intTable(SIZE);
SearchableVector<double> doubleTable(SIZE);
for (count = 0; count < SIZE; count++)
{
intTable[count] = (count * 2);
doubleTable[count] = (count * 2.14);
}
cout << "These values are in intTable:\n";
for (count = 0; count < SIZE; count++)
cout << intTable[count] << " ";
cout << endl << endl;
cout << "These values are in doubleTable:\n";
for (count = 0; count < SIZE; count++)
cout << doubleTable[count] << " ";
cout << endl;
cout << "\nSearching for 6 in intTable.\n";
result = intTable.findItem(6);
if (result == -1)
cout << "6 was not found in intTable.\n";
else
cout << "6 was found at subscript " << result << endl;
cout << "\nSearching for 12.84 in doubleTable.\n";
result = doubleTable.findItem(12.84);
if (result == -1)
cout << "12.84 was not found in doubleTable.\n";
else
cout << "12.84 was found at subscript " << result << endl;
return 0;
}💻 Program Output
Specialized Templates
- A specialized template provides a specific implementation for a template that is designed to work with a particular data type.
- This is useful when a generic template does not work correctly for a specific type, such as C-strings.
- The declaration for a specialized template replaces the type parameter with the actual data type.
class SimpleVector<char *>Checkpoint
16.10 Suppose your program uses a class template named
List, which is defined astemplate<class T> class List { };Give an example of how you would use
intas the data type in the definition of aListobject. (Assume the class has a default constructor.)16.11 As the following
Rectangleclass is written, thewidthandlengthmembers aredoubles. Rewrite the class as a template that will accept any data type for these members.class Rectangle { private: double width; double length; public: void setData(double w, double l) { width = w; length = l;} double getWidth() { return width; } double getLength() { return length; } double getArea() { return width * length; } };
Review Questions and Exercises
Short Answer
What is a throw point?
What is an exception handler?
Explain the difference between a try block and a catch block.
What happens if an exception is thrown, but not caught?
What is “unwinding the stack”?
What happens if an exception is thrown by a class’s member function?
How do you prevent a program from halting when the new operator fails to allocate memory?
Why is it more convenient to write a function template than a series of overloaded functions?
Why must you be careful when writing a function template that uses operators such as
[]with its parameters?
Fill-in-the-Blank
The line containing a throw statement is known as the ___________ .
The ___________ block contains code that directly or indirectly might cause an exception to be thrown.
The ___________ block handles an exception.
When writing function or class templates, you use a(n) ___________ to specify a generic data type.
The beginning of a template is marked by a(n) ___________ .
When defining objects of class templates, the ___________ you wish to pass into the type parameter must be specified.
A(n) ___________ template works with a specific data type.
Algorithm Workbench
Write a function that searches a numeric array for a specified value. The function should return the subscript of the element containing the value if it is found in the array. If the value is not found, the function should throw an exception.
Write a function that dynamically allocates a block of memory and returns a
charpointer to the block. The function should take an integer argument that is the amount of memory to be allocated. If thenewoperator cannot allocate the memory, the function should return a null pointer.Make the function you wrote in Question 17 a template.
Write a template for a function that displays the contents of an array of any type.
True or False
T F There can be only one catch block in a program.
T F When an exception is thrown, but not caught, the program ignores the error.
T F Data may be passed with an exception by storing it in members of an exception class.
T F Once an exception has been thrown, it is not possible for the program to jump back to the throw point.
T F All type parameters defined in a function template must appear at least once in the function parameter list.
T F The compiler creates an instance of a function template in memory as soon as it encounters the template.
T F A class object passed to a function template must overload any operators used on the class object by the template.
T F Only one generic type may be used with a template.
T F In the function template definition, it is not necessary to use each type parameter declared in the template prefix.
T F It is possible to overload two function templates.
T F It is possible to overload a function template and an ordinary (nontemplate) function.
T F A class template may not be derived from another class template.
T F A class template may not be used as a base class.
T F Specialized templates work with a specific data type.
Find the Error
Each of the following declarations or code segments has errors. Locate as many as possible.
catch{quotient = divide(num1, num2);cout << "The quotient is " << quotient << endl;}try (string exceptionString){cout << exceptionString;}try{quotient = divide(num1, num2);}cout << "The quotient is " << quotient << endl;catch (string exceptionString){cout << exceptionString;}template <class T>T square(T number){return T * T;}template <class T>int square(int number){return number * number;}template <class T1, class T2>T1 sum(T1 x, T1 y){return x + y;}Assume the following definition appears in a program that uses the
SimpleVectorclass template presented in this chapter.int <SimpleVector> array(25);Assume the following statement appears in a program that has defined
valueSetas an object of theSimpleVectorclass presented in this chapter. AssumevalueSetis avectorofints, and has 20 elements.cout << valueSet<int>[2] << endl;
Programming Challenges
Date Exceptions
Modify the
Dateclass you wrote for Programming Challenge 1 of Chapter 13 (Date). The class should implement the following exception classes:InvalidDayThrow when an invalid day (< 1 or > 31) is passed to the class. InvalidMonthThrow when an invalid month (< 1 or > 12) is passed to the class. Demonstrate the class in a driver program.
Time Format Exceptions
Modify the
MilTimeclass you created for Programming Challenge 4 of Chapter 15 (Time Format). The class should implement the following exceptions:BadHourThrow when an invalid hour (< 0 or > 2359) is passed to the class. BadSecondsThrow when an invalid number of seconds (< 0 or > 59) is passed to the class. Demonstrate the class in a driver program.
Minimum/Maximum Templates
Write templates for the two functions
minimumandmaximum. Theminimumfunction should accept two arguments and return the value of the argument that is the lesser of the two. Themaximumfunction should accept two arguments and return the value of the argument that is the greater of the two. Design a simple driver program that demonstrates the templates with various data types.Absolute Value Template
Write a function template that accepts an argument and returns its absolute value. The absolute value of a number is its value with no sign. For example, the absolute value of -5 is 5, and the absolute value of 2 is 2. Test the template in a simple driver program.
Total Template
Write a template for a function called
total. The function should keep a running total of values entered by the user, then return the total. The argument sent into the function should be the number of values the function is to read. Test the template in a simple driver program that sends values of various types as arguments and displays the results.IntArrayClass ExceptionChapter 14 presented an
IntArrayclass that dynamically creates an array of integers and performs bounds checking on the array. If an invalid subscript is used with the class, it displays an error message and aborts the program. Modify the class so it throws an exception instead.TestScoresClassWrite a class named
TestScores. The class constructor should accept an array of test scores as its argument. The class should have a member function that returns the average of the test scores. If any test score in the array is negative or greater than 100, the class should throw an exception. Demonstrate the class in a program.SimpleVectorModificationModify the
SimpleVectorclass template presented in this chapter to include the member functionspush_backandpop_back. Thepush_backfunction should accept an argument and insert its value at the end of the array. Thepop_backfunction should accept no argument and remove the last element from the array. Test the class with a driver program.SearchableVectorModificationModify the
SearchableVectorclass template presented in this chapter so it performs a binary search instead of a linear search. Test the template in a driver program.SortableVectorClass TemplateWrite a class template named
SortableVector. The class should be derived from theSimpleVectorclass presented in this chapter. It should have a member function that sorts the array elements in ascending order. (Use the sorting algorithm of your choice.) Test the template in a driver program.Inheritance Modification
Assuming you have completed Programming Challenges 9 and 10, modify the inheritance hierarchy of the
SearchableVectorclass template so it is derived from theSortableVectorclass instead of theSimpleVectorclass. Implement a member function namedsortAndSearch, both a sort and a binary search.Specialized Templates
In this chapter, the section Specialized Templates within Section 16.4 describes how to design templates that are specialized for one particular data type. The section introduces a method for specializing a version of the
SimpleVectorclass template so it will work with strings. Complete the specialization for both theSimpleVectorandSearchableVectortemplates. Demonstrate them with a simple driver program.Exception Project
This assignment assumes you have completed Programming Challenge 1 of Chapter 15 (
EmployeeandProductionWorkerClasses). Modify theEmployeeandProductionWorkerclasses so they throw exceptions when the following errors occur:The
Employeeclass should throw an exception namedInvalidEmployeeNumberwhen it receives an employee number that is less than 0 or greater than 9999.The
ProductionWorkerclass should throw an exception namedInvalidShiftwhen it receives an invalid shift.The
ProductionWorkerclass should throw an exception namedInvalidPayRatewhen it receives a negative number for the hourly pay rate.
Write a driver program that demonstrates how each of these exception conditions works.

Solving the Exception Project Problem