Declaring And Using Class Templates

 < Day Day Up > 



Class templates are used to declare and define a generic class structure. The compiler uses the class template and any types supplied via specialization to build a new class type. Let us begin the discussion of class templates with a simple Foo example. Example 15.8 shows the declaration and definition of a class template named Foo.

Listing 15.8: foodef.h

start example
  1  #ifndef FOOTEMPLATEDEF_H  2  #define FOOTEMPLATEDEF_H  3  4  template<class T>  5  class Foo{  6      public:  7          Foo(T _val);  8          virtual ~Foo();  9          void setVal(T _val); 10          T getVal(); 11      private: 12          T val; 13  }; 14 15  template<class T> 16  Foo<T>::Foo(T _val):val(_val){} 17 18  template<class T> 19  Foo<T>::~Foo(){} 20 21  template<class T> 22  void Foo<T>::setVal(T _val){ 23       val = _val; 24  } 25 26  template<class T> 27  T Foo<T>::getVal(){ 28       return val; 29  } 30  #endif
end example

The declaration of the Foo class templates begins on line 4 with the keyword template. There is only one template parameter declared named T. The T is used throughout the class declaration and definition to reserve a spot for the type declared when the Foo class is specialized. Notice that both the class declaration and definition appear in the same header file.

Refer to line 26. Each Foo class member function definition must be preceded with the template declaration. To keep your source code clean I recommend putting the template declaration on its own line and begin the function definition on the next line down.

Refer to line 27. Notice how the name of the class is Foo<T>, not plain ol' Foo! Otherwise, the definition of class functions proceed as usual except the T placeholder is used where needed. Example 15.9 shows a main() function using the Foo class template with various specializations. Figure 15-6 shows the results of running this program.

Listing 15.9: main.cpp

start example
  1  #include <iostream>  2  #include "foodef.h"  3  using namespace std;    4  5  int main(){  6       Foo<int> f1(1);  7       Foo<char> f2('d');  8       cout<<f1.getVal()<<endl;  9       cout<<f2.getVal()<<endl; 10       return 0; 11  }
end example


Figure 15-6: Results of Running Example 15.9

Referring to line 6 of example 15.9, notice how the Foo class template is specialized to use an int type. The important point to note in this example is that Foo<int> and Foo<char> are two distinct types.

A More Complex Class Template Example

Example 15.10 gives the source code for a template version of the DynamicArray class originally introduced in chapter 14.

Listing 15.10: dynamicarraydef.h

start example
  1  #ifndef _DYNAMIC_ARRAY_H  2  #define _DYNAMIC_ARRAY_H  3  4  template<class T> class DynamicArray{  5    public:  6       DynamicArray(int _size = 5);  7       virtual ~DynamicArray();  8       T& operator[](unsigned i);  9       int getSize(); 10    private: 11       T* its_array; 12       int size; 13  }; 14 15  template<class T> 16  DynamicArray<T>::DynamicArray(int _size):size(_size){ 17       its_array = new T[_size]; 18       for(int i=0; i<size; i++) 19           its_array[i] = static_cast<T>(0); 20  } 21 22  template<class T> 23  DynamicArray<T>::~DynamicArray(){ 24       delete[] its_array; 25  } 26 27  template<class T> 28  T& DynamicArray<T>::operator[](unsigned i){ 29       if(i >= (size)){ 30          int newsize = size+10; 31          T* temp = new T[size]; 32          for(int j = 0; j<size; j++){ 33               temp[j] = its_array[j]; 34           } 35           delete[] its_array; 36          its_array = new T[newsize]; 37          for(int j = 0; j<size; j++){ 38              its_array[j] = temp[j]; 39          } 40 41          for(int j=size; j<newsize; j++){ 42          its_array[j] = static_cast<T>(0); 43          } 44         delete[] temp; 45         size = newsize; 46 47        return its_array[i]; 48      } else return its_array[i]; 49  } 50 51  template<class T> 52  int DynamicArray<T>::getSize(){ return size;} 53 54  #endif
end example

Converting the DynamicArray class into a class template increased its usefulness as it can now be used to hold different types of objects, even user-defined types. Example 15.11 gives a main() function showing the DynamicArray class template in use.

Listing 15.11: main.cpp

start example
  1  #include <iostream>  2  using namespace std;  3  #include "dynamicarraydef.h"  4  5  int main(){  6       DynamicArray<char> d1;  7       DynamicArray<float> d2;  8  9       for(int i=0; i<6; i++){ 10           d1[i] = 'a'; 11       } 12       for(int i=0; i<6; i++){ 13           d2[i] = (i + .5); 14       } 15 16 17       for(int i=0; i<d1.getSize(); i++){ 18           cout<<d1[i]<<"      "<<d2[i]<<endl; 19       }      20 21       return 0;   22  }
end example

Figure 15-7 shows the results of running example 15.11.

click to expand
Figure 15-7: Results of Running Example 15.11

Quick Review

Class templates provide a way to write generic classes to gain an additional measure of code reuse. Class template declarations are started with the template keyword followed by the template parameter list. Although not shown in the two class template examples above, class templates can have more than one template parameter.

Group class template declaration and definition in a common header file unless your compiler supports their separation. Consult your compiler documentation.



 < Day Day Up > 



C++ for Artists. The Art, Philosophy, and Science of Object-Oriented Programming
C++ For Artists: The Art, Philosophy, And Science Of Object-Oriented Programming
ISBN: 1932504028
EAN: 2147483647
Year: 2003
Pages: 340
Authors: Rick Miller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net