(Latest Revision: Wed Apr 2 23:34:56 PST 2003 ) ch08_Notes03_Templates

ch08 Notes on Templates

Simple Template Example


/* FILENAME: class.h */

/* Declares a template parameter T to be a stand-in for what might be any particular class. This class definition describes a whole family of classes -- one class for each possible choice of what T might represent. (Incidentally, the choice of the letter T is arbitrary -- any identifier will do as long as we are consistent.) */


template <class T>
class aClass
{
public:
   aClass();
   aClass(T InitialData);

   void SetData(T NewData);
   T Data();

private:
   T TheData;
};  // end class

/* Note the unusual usage of the #include directive below. Normally this would be considered "bad style." Here it is part of a "kludge" or "necessary evil" that allows the compiler to see how the template will be used in the program. Most compilers need to know the information for a lot of reasons. For example, it needs to know how much storage to allocate to variables, and it needs to check to see that the types of actual parameters to functions match the formal parameters. */


#include "class.cpp"  

/* End of header file "class.h" */


/* FILENAME: main.cpp */

/* Simple program that uses the class template above. */


    /* Since class.h includes class.cpp, the include statement
       below has the effect of including both class.h and
       class.cpp.  We are supposed to compile the program with a
       command such as:

            g++ main.cpp

       and not 

            g++ main.cpp class.cpp

       Thus we do not allow separate compilation of
       main.cpp and class.cpp, but force all the source code to
       be compiled as one large file.  Most compilers need this
       "help."  */

#include "class.h" 
#include <iostream.h>  

int main()
{


   aClass<int>     A;  // TheData is an int
   aClass<double>  B(4.8); //TheData is a double == 4.8

   A.SetData(5);
   cout << B.Data() << endl;
}

/* End of main program file "main.cpp" */


/* FILENAME: class.cpp */

/* The code below shows how to implement the class operations. Note that each method definition is preceded by another of the "template <class T>" declarations. Also each time the name of the class ("aClass") occurs behind the scope resolution operator, it is followed by "<T>" */


template <class T>
aClass<T>::aClass() : TheData(0)

/* Note that the compiler would not know what kind of
code to generate to assign "0" to TheData if class.cpp were compiled
independently from main.cpp.  It would have to generate code that
'figures out' how to do the assignment at runtime.  Because of this kind of
problem, it makes the compiler's job easier when we include class.cpp in
main.cpp.  The compiler then knows it will be assigning an integer or real
to TheData. */

{
}  // end default constructor

template <class T>
aClass<T>::aClass(T InitialData): TheData(InitialData)
{
}  // end constructor

template <class T>
void aClass<T>::SetData(T NewData)
{
   TheData = NewData;
}  // end SetData

template <class T>
T aClass<T>::Data()
{
   return TheData;
}  // end Data