With class based programs, you spend a lot of time developing classes that are intended
to be used in many different programs. Your classes must be reliable. After all, no one
else is going to use your classes if they crash the program as soon as they run in to data
that incorrect, or attempt some input or output transfer that fails.
You should aim to build defences into the code of your classes so that bad data won't
cause disasters. So, how might you get given bad data and what kind of defence can
you build against such an eventuality?
"Bad data" most frequently take the form of inappropriate arguments passed in a call
to a member function that is to be executed by an instance of one of your classes, or, if
your objects interact directly with the user, will take the form of inappropriate data
directly input by the user.
You can do something about these relatively simple problems. Arguments passed to
a function can be checked using an assert() macro. Thus, you can check that the
pointers supposed to reference data structures are not NULL, and you can refuse to do
things like sort an array with -1234 data elements (e.g. assert(ptr1 != NULL);
assert((n>1) && (n<SHRT_MAX))). Data input can be handled through loops that
only terminate if the values entered are appropriate; if a value is out of range, the loop is
again cycled with the user prompted to re-enter the data.
Such basic checks help. Careless errors in the code that invokes your functions are
soon caught by assert() macros. Loops that validate data are appropriate for
interactive input (though they can cause problems if, later, the input is changed to come
from a file).
But what happens when things go really wrong? For example, you hit "end of file"
when trying to read input, or you are given a valid pointer but the referenced data
structure doesn't contain the right information, or you are given a filename but you find
that the file does not exist.
void X::GetParams(const char fname)
Simple checks on