CPP Templates

What is Templates?

  • Templates are so useful that a library containing a number of routines using templates has been adopted into the definition of the C++ language.
  • C++ contains a Standard Template Library (STL) and a great reference is available here .
  • Templates were not a part of the original C++ language.
  • They are type-safe and very flexible.
  • Templates enable you to create a class that can have the type of the things it works on to be changed.
  • The best way to learn about templates is to create your own.
  • In a commercial program, however, you would almost certainly use the STL classes.
  • Building a Template Definition:
    template <class T>
    Template and class are keywords that you use. T is a character you select to be a placeholder—like a variable name for the template to work on.
    Example template of a Vector Class:
    template <class T>  // Declare the template and the parameter
    class Vector    {   // the class being parameterized
    public:
      // Constructors
      Vector(int size = 5);
      Vector(const Vector &rVector);
      ~Vector() { delete [] pType; }
    
      // Overloaded operators
      Vector& operator=(const Vector&);
      T & operator[](int offSet) { return pType[offSet]; }
      const T& operator[](int offSet) const
      { return pType[offSet]; }
      // Accessors
      int getSize() const { return size; }
    
    private:
      T *pType;
      int  size;
    };
  • When an instance of a double array is defined, T is replaced with a double, so the operator[ ] that is provided to that array returns a reference to a double. This is equivalent to the following:
    double & operator[](int offSet) { return pType[offSet]; }
    
  • When an instance of a Rectangle array is declared, the operator[ ] provided to the Rectangle array returns a reference to a Rectangle:
    Rectangle & operator[](int offSet) { return pType[offSet]; }
    
  • To write implementation outside the class declaration you have to follow this notation:
    1. Declare the template and the parameter in the front of each method implementation.
    2. The specification of the class must include the parameter.
    Full Example template of a Vector Class:
    #include <iostream>
    
    // Declare a simple Rectangle class so that we can
    // create a vector of rectangles
    class Rectangle {
    public:
      Rectangle(int width, int height);
      Rectangle();
      ~Rectangle() {}
      int getHeight() const { return height; }
      int getWidth() const { return width; }
      void Area() const { std::cout << "the area:\t " << width*height ; }
    private:
      int width;
      int height;
    };
    
    Rectangle::Rectangle(int width, int height){
      this->width=width;
      this->height= height;
    }
    
    Rectangle::Rectangle(){
      this->width=0;
      this->height=0;
    }
    
    template <class T>  // Declare the template and the parameter
    class Vector    {   // the class being parameterized
    public:
      // Constructors
      Vector(int size = 5);
      Vector(const Vector &rVector);
      ~Vector() { delete [] pType; }
    
      // Overloaded operators
      Vector& operator=(const Vector&);
      T & operator[](int offSet) { return pType[offSet]; }
      const T& operator[](int offSet) const
      { return pType[offSet]; }
      // Accessors
      int getSize() const { return size; }
    
    private:
      T *pType;
      int  size;
    };
    // Implement the Constructor
    template <class T>              // Declare the template and the parameter
    Vector<T>::Vector(int size) {   // All class spec. must be ClassName<T>
      this->size=size;
      pType = new T[size];
      // the constructors of the type you are creating
      // should set a default value
    }
    
    // Copy constructor
    template <class T>
    Vector<T>::Vector(const Vector<T> & rVector){
      size = rVector.getSize();
      pType = new T[size];
      for (int i = 0; i<size; i++)
        pType[i] = rVector[i];
    }
    
    // operator= Implementation
    template <class T>
    Vector<T>& Vector<T>::operator=(const Vector<T> &rVector){
      if (this == &rVector)
        return *this;
      delete [] pType;
      size = rVector.getSize();
      pType = new T[size];
      for (int i = 0; i<size; i++)
        pType[i] = rVector[i];
      return *this;
    }
    
    int main() {
      Vector<double> theDoubles;         // a vector of 5 doubles
      Vector<Rectangle> theRectangles;   // a vector of 5 Rectangles
      Rectangle * pRectangle;
    
      // Fill the vectors (both vectors are of the same size)
      for (int i = 0; i < theDoubles.getSize(); i++) {
        theDoubles[i] = (i+5)*3;
        pRectangle = new Rectangle((i+2)*3, (i+1)*4);
        theRectangles[i] = *pRectangle;
        delete pRectangle;
      }
      // Print the contents of the vectors
      for (int j = 0; j < theDoubles.getSize(); j++) {
        std::cout << "theDoubles[" << j << "]:\t";
        std::cout << theDoubles[j] << "\t";
        std::cout << "theRectangles[" << j << "] has ";
        theRectangles[j].Area();
        std::cout << std::endl;
      }
      return 0;
    }
    When we run this application, the result will be:
    theIntegers[0]: 15      theRectangles[0] has the area:   24
    theIntegers[1]: 18      theRectangles[1] has the area:   72
    theIntegers[2]: 21      theRectangles[2] has the area:   144
    theIntegers[3]: 24      theRectangles[3] has the area:   240
    theIntegers[4]: 27      theRectangles[4] has the area:   360

    You can download this example here (needed tools can be found in the right menu on this page).

© 2010 by Finnesand Data. All rights reserved.
This site aims to provide FREE programming training and technics.
Finnesand Data as site owner gives no warranty for the correctness in the pages or source codes.
The risk of using this web-site pages or any program codes from this website is entirely at the individual user.