C++. The concept of a class template. The ‘template’ keyword. Advantages of using templates. Examples of declaring and using of class templates. Arguments in templates




The concept of a class template. The ‘template’ keyword. Advantages of using templates. Examples of declaring and using of class templates. Arguments in templates


Contents


Search other websites:

1. What is called a class template? What is a class template?

Often, when developing classes for different types of data, a programmer must write code for each type separately. Methods and operations on data of different types can contain one and the same repeated code. To avoid the repetition of writing code for different types of data, C++ uses so-called templates.

Class template lets you manipulate the data of different types in general. That is, there is no binding to a particular type of data (int, float, …). All work is performed on some generalized data type, for example a type named T.

In fact, the declaration of a class template is only a description. Creating a real class with a given data type is done by the compiler at the time of compilation, when a class object is declared.

2. What is the general form of declaring a class template and a template class object that do not contain arguments? The ‘template’ keyword

In the simplest case, the general form of declaring a class template with no arguments is as follows:

template <class T> class ClassName
{
    // body of class
    // ...
}

where

  • T – a generic type name that is used by class methods;
  • ClassName – the name of the class that contains the methods of handling the generalized type of the class.

The general form of declaring a template class object is as follows:

ClassName <type> objName;

where

  • ClassName – the name of template class;
  • type – a specific type of data in the program;
  • objName – the name of the object (instance) of the class.

The class keyword can be replaced with the word typename. In this case, the general form of declaration for the template class may be as follows:

template <typename T>
class ClassName 
{
    // ...
}

In this case, there is no difference between using the words class and typename.

3. What are the benefits of using class templates?

Declaring a class template provides the following benefits:

  • avoid the repetition of writing code for different types of data. The program code (methods, functions) is written for some generalized type T. The name of the generalized type can be given any, for example TTT;
  • reduction of the text part of the program code, and, as a result, increase the readability of programs;
  • providing a convenient mechanism for passing arguments to the class template for the purpose of processing them using class methods.





4. An example of declaring a class template that contains methods for processing a number whose type can be an integer or a real number

Let it be necessary to declare a class template that will handle a certain number. The number can be any type that allows you to perform arithmetic operations on it. The example declares a class template that contains methods that perform the following operations on some number:

  • multiplying the number by 2;
  • division of one number into another. For integer types, the result of division is an integter number;
  • the square of the number (power of 2).

The template declaration has the form

// template of a class that implements a number of different types
template <class T>
class MyNumber
{
    public:
    // constructor
    MyNumber(void) { }

    // method of multiplying the number by 2
    void Mult2(T* t);

    // a method that returns the square of a number for some type T
    T MySquare(T);

    // A method that divides two numbers of type T and returns a result of type T
    T DivNumbers(T, T);
};

// implementation of a method that multiplies a number by 2
template <class T> void MyNumber<T>::Mult2(T* t)
{
    *t = (*t)*2;
}

// implementation of the method that returns the square of a number
template <class T> T MyNumber<T>::MySquare(T number)
{
    return (T)(number*number);
}

// A method that divides 2 numbers and returns the result of division
template <class T> T MyNumber<T>::DivNumbers(T t1, T t2)
{
    return (T)(t1/t2);
}

Using the MyNumber class template in another code

MyNumber <int> mi; // the mi object of the class works with int type
MyNumber <float> mf; // object mf works with the float type

int d = 8;
float x = 9.3f;

// multiplying the number by 2
mi.Mult2(&d); // d = 16
mf.Mult2(&x); // x = 18.6

// squaring
int dd;
dd = mi.MySquare(9); // dd = 81 - integer number

double z;
z = mf.MySquare(1.1); // z = 1.21000... - real number

// division of numbers
long int t;
float f;

t = mi.DivNumbers(5, 2); // t = 2 - division of integers
f = mf.DivNumbers(5, 2); // f = 2.5 - division of real numbers

5. The general form for declaring a template for a class that takes arguments

There are times when you need to use some arguments in the class template. These arguments can be used by methods that are described in the class template.

The general form of the class template containing the arguments is:

template <class T, type1 var1, type2 var2, ..., typeN varN> class ClassName
{
    // body of the class template
    // ...
}

where

  • T – some generalized data type;
  • type1, type2, …, typeN – a specific arguments types named var1, var2, …, varN;
  • var1, var2, …, varN – the names of arguments that is used in the class template.

The general form of declaring an object of a template class containing one argument:

ClassName <type, arg> objName;

where

  • ClassName – the name of a template class;
  • type – specific data type for which the real class is formed;
  • arg – the value of the argument that is used in the class template;
  • objName – the name of the object of template class.

6. An example of using a class template that takes two arguments

In the example, the CMyArray class template is implemented, which contains methods for processing the array of numbers. The type of array elements can be real or integer.

The class template receives two integers:

  • count is the number of elements in the array. It is used to initialize a class with a constructor with one parameter;
  • num is the number used to perform operations on the array.

These numbers are used in methods to perform operations on an array. The class template contains the following data and methods:

  • number of elements in array n;
  • an array of elements (numbers) A of a given dimension (10);
  • the Power() method that implements the values of elements of array A to the power of num. The num value is the input parameter (argument);
  • method CalcNum(), which implements the calculation of the number of elements that are greater than the specified num parameter.

The class template text is as follows:

// template of a class that receives 2 parameters
template <class TT, int count, int num> class CMyArray
{
    private:
    int n; // number of array elements
    TT A[10]; // array of elements

    public:
    // class constructor without parameters
    CMyArray()
    {
        // the number of elements is taken from the input parameter count
        n = count;

        // fill array with arbitrary values
        for (int i=0; i<n; i++)
            A[i] = (TT)(i*2);
    }

    // class constructor with 1 parameter
    CMyArray(int cnt)
    {
        if (cnt<=10) n = cnt;
        else n = 0;

        // fill array with arbitrary values
        for (int i=0; i<n; i++)
            A[i] = (TT)(i*2);
    }

    // access methods
    int GetN(void) { return n; }

    void SetN(int n)
    {
        if (n<=10) this->n = n;
        else n=0;

        for (int i=0; i<n; i++)
            A[i] = (TT)(i*2);
    }

    // A method that returns the value of an array element with a given index
    TT GetItem(int index) { return (TT)A[index]; }

    // methods that perform operations on array A
    // raising array elements to the power of num
    void Power(void);

    // counting the number of elements whose values are greater than num
    int CalcNum(void);
};

// raising the value of array elements to the power of num
template <class TT, int count, int num>
void CMyArray<TT, count, num>::Power(void)
{
    if (n<0) return;

    for (int i=0; i<n; i++)
        A[i] = System::Math::Pow(A[i], num);
}

// A method that determines the number of elements in an array
// that are greater than a specified number num (num is an incoming parameter)
template <class TT, int count, int num>
int CMyArray<TT, count, num>::CalcNum(void)
{
    int k = 0;
    // counting cycle
    for (int i=0; i<n; i++)
        if (A[i] > num)
            k++;
    return k;
}

Using a template in some other program code (function, method)

// Using the CMyArray сlass template
// array of integers, parameters: count = 7, num = 2
CMyArray <int, 7, 2> ai1;

// array of integers, call the constructor with 1 parameter
CMyArray <int, 8, -3> ai2(6); // number of elements count = 6, num = -3

// array of real numbers of type double, call of the constructor without parameters
CMyArray <double, 4, 5> ad1;

// test
int n, t;
double x;

n = ai1.GetN(); // n = 7
n = ai2.GetN(); // n = 6
n = ad1.GetN(); // n = 4

// array check
t = ai1.GetItem(3); // t = 6
t = ai2.GetItem(0); // t = 0
x = ad1.GetItem(2); // x = 4.0

// calling array processing methods and checking the result
ai1.Power(); // the array element in degree num=2
t = ai1.GetItem(3); // t = 6^2 = 36

// Counting the number of elements that are greater than -3
// total in an array of class ai2 6 elements
t = ai2.CalcNum(); // t = 6

// working with a class that implements the double type
x = ad1.GetItem(3); // x = 6.0
ad1.Power(); // the numbers of the array x in degree num = 5
x = ad1.GetItem(3); // x = 6.0^5 = 7776


Related topics