Explain the use of class templates in C++ programming

  • 2020-05-05 11:36:43
  • OfStack

Sometimes, there are two or more classes with the same functionality but different data types, such as the following statement declaring a class:


class Compare_int
{
public :
  Compare(int a,int b)
  {
   x=a;
   y=b;
  }
  int max( )
  {
   return (x>y)?x:y;
  }
  int min( )
  {
   return (x<y)?x:y;
  }
private :
  int x,y;
};

Its purpose is to compare two integers, and you can get the larger and smaller of the two integers by calling the member functions max and min.

If you want to compare two floating point Numbers (float type), you need to declare another class:


class Compare_float
{
public :
  Compare(float a,float b)
  {
   x=a;y=b;
  }
  float max( )
  {
   return (x>y)?x:y;
  }
  float min( )
  {
   return (x<y)?x:y;
  }
private :
  float x,y;
}

Obviously this is basically repetitive work and there should be ways to reduce it.

C++ added templates (template) at a later stage of development to provide a solution to this problem. You can declare a generic class template, which can have one or more dummy type parameters, such as the above two classes can be combined to write the following class template:


template <class numtype> // Declare a template with the virtual type name numtype
class Compare // Class template name Compare
{
public :
  Compare(numtype a,numtype b)
  {
   x=a;y=b;
  }
  numtype max( )
  {
   return (x>y)?x:y;
  }
  numtype min( )
  {
   return (x<y)?x:y;
  }
private :
  numtype x,y;
};

Compare this type of template to the first Compare_int class above, and you can see two differences.

1) add an
line when declaring class templates


  template <class  Type parameter name >


template means "template" and is a keyword that must be written when declaring a class template. The content in the Angle brackets after template is the parameter table column of the template, and the keyword class indicates that the type parameter is followed. In this case numtype is a type parameter name. The name can be arbitrary, as long as it is a valid identifier. numtype here just means "data type". At this point, mimtype is not an existing actual type name, it is just a virtual type parameter name. It will be replaced by an actual type name later.

2) replace the original type name int with the virtual type parameter name numtype.
When creating a class object, if the actual type is specified as int, the compilation system replaces all numtype with int, and float with numtype if specified as float. This can achieve "a kind of multi-purpose."

Because the class template contains type parameters, it is also called a parameterized class. If a class is an abstraction of an object and an object is an instance of a class, then a class template is an abstraction of a class and a class is an instance of a class template. Class templates can be used to create classes with various data types.

So, after declaring a class template, how do you use it? How do you make it an actual class?

Let's review how to define objects using classes:


  Compare_int cmp1(4,7); // Compare_int Is a declared class 


It creates an object of the Compare_int class and assigns arguments 4 and 7 to the parameters a and b, respectively, as two integers for a row comparison.

Defining objects in a class template is similar, but you cannot write
directly


  Compare cmp(4,7); // Compare Is the name of the class template 

Compare is the name of the class template, not a concrete class. The type numtype in the body of the class template is not an actual type, but a virtual type, which cannot be used to define objects. The virtual type must be replaced by an actual type name,


  Compare <int> cmp(4,7);


The actual type name is specified in Angle brackets after the class template name. At compile time, the compilation system replaces the type parameter numtype in the class template with int, thus externalizing, or instantiating, the class template. At this moment Compare< int > This is equivalent to the Compare_int class described earlier.

Declare a class template that can be used to compare two integers, floating point Numbers, and characters to find large Numbers and decimals.


#include <iostream>
using namespace std;
template <class numtype>
// Define class templates 
class Compare
{
  public :
  Compare(numtype a,numtype b)
  {x=a;y=b;}
  numtype max( )
  {return (x>y)?x:y;}
  numtype min( )
  {return (x<y)?x:y;}
  private :
  numtype x,y;
};
int main( )
{
  Compare<int > cmp1(3,7); // Define the object cmp1 , used to compare two integers 
  cout<<cmp1.max( )<<" is the Maximum of two integer numbers."<<endl;
  cout<<cmp1.min( )<<" is the Minimum of two integer numbers."<<endl<<endl;
  Compare<float > cmp2(45.78,93.6); // Define the object cmp2 , used to compare two floating point Numbers 
  cout<<cmp2.max( )<<" is the Maximum of two float numbers."<<endl;
  cout<<cmp2.min( )<<" is the Minimum of two float numbers."<<endl<<endl;
  Compare<char> cmp3( ' a ' , ' A ' ); // Define the object cmp3 , for the comparison of two characters 
  cout<<cmp3.max( )<<" is the Maximum of two characters."<<endl;
  cout<<cmp3.min( )<<" is the Minimum of two characters."<<endl;
  return 0;
}

The results are as follows:


7 is the Maximum of two integers.
3 is the Minimum of two integers.

93.6 is the Maximum of two float numbers.
45.78 is the Minimum of two float numbers.

a is the Maximum of two characters.
A is the Minimum of two characters.

One more thing to note: the member functions in the class template listed above are defined within the class template. If you define it outside the class template instead, you cannot define it as a class member function:
   


 numtype Compare::max( ) { ... } // Member functions in a class template cannot be defined in this way 

Instead, it should be written as a class template:


class Compare_float
{
public :
  Compare(float a,float b)
  {
   x=a;y=b;
  }
  float max( )
  {
   return (x>y)?x:y;
  }
  float min( )
  {
   return (x<y)?x:y;
  }
private :
  float x,y;
}
0

The first line above represents the class template, numtype on the left side of the second line is the virtual type name, Compare < on the back numtype > It's a whole, it's a class with arguments. Indicates that the max function defined is in class Compare < numtype > Of the scope of. When defining an object, the user of course specifies the actual type (int, for example), and at compile time the virtual type name numtype in the class template is all replaced by the actual type. Such Compare < numtype > It's an actual class. You can rewrite the example to define member functions outside of the class template.

To summarize the above, you can declare and use the class template:
1) write an actual class first. Because its semantics is clear, the meaning is clear, won't make a mistake commonly.

2) replace the type name to be changed in this class (such as int to float or char) with a self-specified virtual type name (numtype in the example above).

3) add a line before the class declaration in the format
     


class Compare_float
{
public :
  Compare(float a,float b)
  {
   x=a;y=b;
  }
  float max( )
  {
   return (x>y)?x:y;
  }
  float min( )
  {
   return (x<y)?x:y;
  }
private :
  float x,y;
}
1

Such as:


class Compare_float
{
public :
  Compare(float a,float b)
  {
   x=a;y=b;
  }
  float max( )
  {
   return (x>y)?x:y;
  }
  float min( )
  {
   return (x<y)?x:y;
  }
private :
  float x,y;
}
2

4) define objects with class templates in the following form:


   Class template name < Actual type name >  Object name ;
   Class template name < Actual type name >  Object name ( The argument list );


Such as:


class Compare_float
{
public :
  Compare(float a,float b)
  {
   x=a;y=b;
  }
  float max( )
  {
   return (x>y)?x:y;
  }
  float min( )
  {
   return (x<y)?x:y;
  }
private :
  float x,y;
}
4

5) if a member function is defined outside the class template, it should be written in the form of class template:


class Compare_float
{
public :
  Compare(float a,float b)
  {
   x=a;y=b;
  }
  float max( )
  {
   return (x>y)?x:y;
  }
  float min( )
  {
   return (x<y)?x:y;
  }
private :
  float x,y;
}
5

class Compare_float
{
public :
  Compare(float a,float b)
  {
   x=a;y=b;
  }
  float max( )
  {
   return (x>y)?x:y;
  }
  float min( )
  {
   return (x<y)?x:y;
  }
private :
  float x,y;
}
6


A few notes about class templates:
1) there can be one or more type parameters of the class template, and class must be added before each type, such as:


class Compare_float
{
public :
  Compare(float a,float b)
  {
   x=a;y=b;
  }
  float max( )
  {
   return (x>y)?x:y;
  }
  float min( )
  {
   return (x<y)?x:y;
  }
private :
  float x,y;
}
7


When defining an object, substitute the actual type name, such as
, respectively


  someclass<int,double> obj;

2) as with classes, be aware of the scope of the class template, which can only be used to define objects within its valid scope.

3) templates can have levels, a class template can be used as a base class, derived from the derived template class. The practical application of this knowledge is limited, this tutorial will not be introduced, interested students can learn on their own.


Related articles: