Section 3 - Applying the Template to Other Types

8A.3.1 A Safe Class of Strings

The hard work is done.  Now we can use this SafeArray template for other types.  Let's try a SafeArray of strings.  No change to the class whatsoever.  No derived classes.  We just change the client:

#include <sstream>
int main()
{
  int k;
  SafeArray<string> studentNames(5);

  // assign data and go out-of-bounds
  for (k = -3; k < 10; k++)
  {
    string stringNum;
    ostringstream cnvrt;
    cnvrt << k;
    stringNum = cnvrt.str();

    studentNames[k] = "student # " + stringNum;
  }

  cout << "The array after some assignments:\n";
  for (k = -3; k < 10; k++)
    cout << studentNames[k] << endl;

  // test the assignment operator
  SafeArray<string> employeeNames(40);
  employeeNames = studentNames;
  cout << "Did employeeNames[2] get assigned studentNames[2]?\n";
  cout << employeeNames[2] << " " << studentNames[2] << endl;

  return 0;
}

Here is the output:

console shot

As you see, this template easily and correctly handled the change to string type in main().  We only had to change our main() statements to assign string values, but this is to be expected.

8A.3.2 Reflection

We created a data structure called SafeArray without committing to the kind of data that it took.  We declared it to be a template class.  Then, we instantiated a SafeArray by declaring the type we wanted to use: float in one example and string in another. The class worked perfectly fine in either case!

We could have declared a SafeArray of Cards with this statement;

SafeArray<Card> deck(52);

This would enable us to use the deck without worrying about bounds checking.  Of course, our Deck class from the last lesson has so much power we wouldn't want to give that up.  Hmmm.  Things to think about:

These are not necessarily easy questions, but they are not impossible ones either.  The remaining sections of this module give us a big hint.