Broad Network


C++ Class Templates

C++ Templates – Part 2

Forward: Like a function template, a class template is a class that uses generic object types. In this part of the series, I show you how to create a class template.

By: Chrysanthus Date Published: 24 Aug 2012

Introduction

This is part 2 of my series C++ Templates. You should have read the previous part before reading this one. Like a function template, a class template is a class that uses generic object types. In this part of the series, I show you how to create a class template.

Note: If you cannot see the code or if you think anything is missing (broken link, image absent), just contact me at forchatrans@yahoo.com. That is, contact me for the slightest problem you have about what you are reading.

Ordinary Class
Consider the following code:

#include <iostream>
using namespace std;

class Calculator
    {
        public:
        int num1;
        int num2;

        Calculator(int ident1, int ident2)
            {
                num1 = ident1;
                num2 = ident2;
            }

        int add ()
            {
                int sum = num1 + num2;
                return sum;
            }
    };


int main()
    {
        Calculator myObject(2,3);
        int result = myObject.add();
        cout << result;

        return 0;
    }

In the code you have a class called, Calculator. It has a constructor function that initializes the properties, num1 and num2. The class has one method, add(), which adds two ints (num1 to num2). We know in advance that these two property values will be ints, because of their declaration types. Properties and methods of a class are called members of the class. In the main function, the first statement creates an object called, myObject. In this creation process the values 2 and 3 are sent to initialize the object (that is, initialize the properties, num1 and num2).

Class Template Example
For a class template the type of values for the properties are determined when an object for the class is created (instantiated). In the following template class code, the first and second property value types (int and float) are determined when the object for the class is instantiated. With class template, you cannot know the type of arguments (values) for the properties in advance. In that way, different types of arguments (property values) can be used for the same class. Different argument types cannot be used in the creation (instantiation) of an object from an ordinary class.

#include <iostream>
using namespace std;

template <class T, class U>
class Calculator
    {
        public:
        T num1;
        U num2;

        Calculator(T ident1, U ident2)
            {
                num1 = ident1;
                num2 = ident2;
            }

        U add ()
            {
                U sum = num1 + num2;
                return sum;
            }
    };


int main()
    {
        Calculator<int, float> myObject(2,3.4);
        float result = myObject.add();
        cout << result;

        return 0;
    }

A class template begins with the keyword, template. Then you have a space and the template parameter declarations (in angle brackets). Each parameter here begins with the word, class then a space and then the object type placeholder. The parameter declarations are separated by commas and are all in angle brackets. After that you have the class description. In the description, the object type placeholders are used as object types. It is through these placeholders that you have generic object types.

In the main function, the first statement instantiates the object. When instantiating the object the template precise argument types in angle brackets are typed just next to the class name. That is the argument types for property values are typed in angle brackets next to the class name. Then you have a space before the name you want to give for the object.

Class without Constructor
Let us look at a class template, where the class description does not have a constructor. The following code works well:

#include <iostream>
using namespace std;

template <class T, class U>
class Calculator
    {
        public:
        T num1;
        U num2;

        U add (T ID1, U ID2)
            {
                U sum = ID1 + ID2;
                return sum;
            }
    };


int main()
    {
        Calculator<int, float> myObject;
        float result = myObject.add(6,2.7);
        cout << result;

        return 0;
    }

Read through the code. The lesson to learn from here is that whether the template class has a constructor function or not, when instantiating the object, the template argument list (e.g. <int, float>) must be typed just after the class name (for instantiation), as in the first line in the main function above. In that way the object types for the type placeholders are determined when the object is created as expected; not before it is created (when the class is described).

With template functions, when calling the function, the presence of the template argument list typed before the function calling parentheses, is optional. With methods of object, you do not use it before the calling parentheses.

Mixing Generic with Specific Argument Types
With function templates, if you want to mix generic and specific argument types, then specific types will not be indicated in the template parameter list; they will be indicated in the function parameter list, normally. However, with Class templates they are indicated in the template parameter list. While in the template parameter list, they behave as class additional properties. The following code illustrates the use of specific object type with class template:

#include <iostream>
using namespace std;

template <class T, class U, bool B>
class Calculator
    {
        public:
        T num1;
        U num2;

        U add (T ID1, U ID2)
            {
                if (B == true)
                    {
                        return ID1 + ID2;
                    }
                else
                    {
                        return ID1 - ID2;
                    }
            }
    };


int main()
    {
        Calculator<int, float, true> myObject;
        float result = myObject.add(6,2.7);
        cout << result;

        return 0;
    }

Note that the parameter declaration for the specific object type is found only in the template parameter list. It is not found as a property in the class. It is however used in the class method. In the instantiation of the class, it is the value of the specific object type that is in the template argument list and not the specific type. In the above case you have the value, true in the template argument list and not bool, which is the Boolean type in the template parameter list.

Defining Method outside Class Description
The following code illustrates how a method can be defined outside the class description for a template class:

#include <iostream>
using namespace std;

template <class T, class U>
class Calculator
    {
        public:
        T num1;
        U num2;

        U add (T ID1, U ID2);
    };

    template <class T, class U>
    U Calculator<T, U>::add (T ID1, U ID2)
        {
            U sum = ID1 + ID2;
            return sum;
        }

int main()
    {
        Calculator<int, float> myObject;
        float result = myObject.add(6,2.7);
        cout << result;

        return 0;
    }

Inside the class description you have just the method prototype to indicate that the method exist in that position. Outside you have the definition of the method. It begins with a repeat typing of the keyword, template and its parameter list. You then have in a new line, the returned type placeholder for the method. Then a space, the name of the class and the template parameter identifiers, separated by comma(s), in angle brackets. Next you have the scope resolution operator (::). After that the rest of the method definition is as you would find in an ordinary method definition, but with type placeholder where generic type is expected.

Note: All type placeholders in the angle brackets of the template parameter declarations have to be used in the class description. In the above case, T and U have been used in the class description.

Class Template Declarations
Just as template functions have declarations (prototypes), template classes also have declarations. A template class that has or does not have a constructor function, is declared something, like,

template <class T, class U> class Calculator;

Note the semicolon at the very end.

Read and try the following code:

#include <iostream>
using namespace std;

template <class T, class U> class Calculator;

template <class T, class U>
class Calculator
    {
        public:
        T num1;
        U num2;

        Calculator(T ident1, U ident2)
            {
                num1 = ident1;
                num2 = ident2;
            }

        U add ()
            {
                U sum = num1 + num2;
                return sum;
            }
    };


int main()
    {
        Calculator<int, float> myObject(2,3.4);
        float result = myObject.add();
        cout << result;

        return 0;
    }

C++ Interface and Implementation
A typical C++ program has header files. In a header file you have interfaces (declarations) of functions and classes. You have the implementation of these in either normal C++ files or in libraries. You cannot split a template function or template class this way. This is because templates are compiled at run time (execution phase), not before run time. So any template (function or class) that you have, must be in one file. This means if you have a template spit into interface and implementation, both the interface and implementation must be in one file.

That is it for Class Template. We have come to the end of the series. I hope you appreciated it.

Chrys

Related Courses

C++ Course
Relational Database and Sybase
Windows User Interface
Computer Programmer – A Jack of all Trade – Poem

Comments

Become the Writer's Fan
Send the Writer a Message