You will need to deal with three things to utilize exceptions in your code:
1. Define your own exception class (which can be a sub-class of one of the existing exception classes as explained below).
2. Throw your exception in your code when the error conditions have been met.
3. Catch your thrown exception and deal with in in a try / catch statement.
More information for each of these steps is given here.
You will want to create one or more files to define your exceptions. The easiest way to create a new exception class in C++ is by defining a sub-class of the existing exceptions in the stdexcept / exception library.
#include<stdexcept>
#include <string>
using namespace std;
class NewException : public out_of_range
{
public:
NewException(const string & message ="")
: out_of_range(message.c_str())
{} //Don't Forget these brackets!
}
This defines a NewException class which is a sub-class of out_of_range. In this class we have a default constructor which assigns the string parameter to the message private variable of the out_of_range class. (the function c_str() converts the string to a c-style string i.e. a character array.) The new constructor is needed because sub-classes do not inherit the constructor and destructor of the parent class.
The public keyword in the class definition indicates that functions that were previously public in the parent class should remain public in the child class. Because of this we can call the what() function as we will see below.
To make use of an exception such as the example above, one could create a header file called “Exceptions.h” and place this class definition inside this file. Make sure to use the #ifndef set-up in this header file to avoid multiple inclusions of this exception header.
Then if were used by a particular class, Exceptions.h would first be included in that classes header file.
Then the function definition of the function that threw this exception would be modified to include this information. Here is an example:
Matrix Matrix::inverse( ) const throw(NewException);
Inside this function, the exception would be thrown like this:
throw NewException("error: message");
This thrown exception would need to be caught somewhere. Usually this occurs in the method that has called the function. For lab 2, these exceptions will be caught in the main method of the program.
try {
m.inverse()
catch(NewException e)
{
cout << e.what() << endl;
}
e is the NewException object created by the throw. It contains the error message string.
The what() method is part of the parent class out_of_range and returns the value of the message variable which we assign to be the error message for the exception in the exception header file.
Here are the classes in the stdexcept. These are in the namespace std. Indention indicates sub-classing.
logic_error
domain_error
invalid_argument
length_error
out_of_range
runtime_error
range_error
overflow_error
underflow_error
You could sub-class any of these exception class.
Also, all of these classes are sub-classes of the exception class, which you could sub-class directly.
More information on these exceptions
Remember, pointers store the address of a value stored somewhere else on the computer memory. Pointers point to strings / numbers / objects, but aren’t actually any of those things.
Here are the common usages of pointers.
int *p; //-- creates a pointer that can point to integers
string *s; //-- creates a pointer that can only point to string objects
int x = 7; //-- x is just a normal integer
p = &x; //-- indicates that the pointer p now
// contains the memory address of the variable x.
// So p points to x.
*p = 2; //-- this changes the value stored in the address held by p.
// Meaning *p and x will change.
int *q; //-- q is another integer pointer.
q = p; //-- q and p point to the same thing.
// Meaning, p and q now contain the same memory address.
Here is some more code you’ll want to add to the error checking portion of your main function
// Attempt to open the specified input file and confirm that it has been opened correctly
ifstream in(argv[1]);
if (in.bad())
{
cerr << "Error: Failed to open input file." << endl;
return 1;
}
The new portion is the if statement. It calls the bad() method of the ifstream instance. This you can find more information about on the reference site, but essentially it will return true if there was an error opening the file. You’ll probably want to add similar code for the output file.
Two ways I have found to work for this project.
ifstream inputFile (argv[1]);
while(!inputFile.eof())
{
//...
}
This seems to work for the sample file, and so will probably work fine for this project.
Problems with this method:
ifstream inputFile (argv[1]);
string command;
while(1)
{
inputFile >> command;
if(inputFile.fail())
{
break;
}
// ...
}
So, This method breaks out of the while loop when the fail method of the inputFile returns true. It returns true if an input operation doesn’t succeed for any reason. This is usually because of an illegal character or the end of file.