类模板

类模板:数据的组织方式和数据元素的类型无关。(也就是存储和组织元素)。

   (链表类,队列类)。不关心操作的数据元素类型,只关心操作方法。

语法:

template < typename T >   // T 泛指类型,具体的元素类型
class Operator           // 类模板名
{
public:
    T function(T a, T b)   // function 具体的操作方法
    {  }
};

 类模板定义具体对象:(必须显示的指定元素类型,编译器无法自动推导类型)

Operator<string> str_op; // 用类模板Operator定义一个操作元素为string类的对象str_op。编译器此处生成str_op类的实体。

编译器对类模板的处理:编译器通过具体参数和类模板在定义对象时生成类的实体。

           编译器会对类模板本身代码进行一次编译,还会对参数替换后的类的代码进行一次编译。

注意:类模板在头文件里定义。

   类模板的成员函数在外部实现时要加上模板<>声明。

   类模板不能分开实现在不同的文件中。

template < typename T >     // 类模板函数在外部实现时的声明方式
T Operator<T>::function(T a, T b)
{
    /* do something */
}

加减乘除类模板的实现:

#ifndef _OPERATOR_H_
#define _OPERATOR_H_

template < typename T >
class Operator
{
public:
    T add(T a, T b);
    T minus(T a, T b);
    T multiply(T a, T b);
    T divide(T a, T b);
};

template < typename T >
T Operator<T>::add(T a, T b)
{
    return a + b;
}

template < typename T >
T Operator<T>::minus(T a, T b)
{
    return a - b;
}

template < typename T >
T Operator<T>::multiply(T a, T b)
{
    return a * b;
}

template < typename T >
T Operator<T>::divide(T a, T b)
{
    return a / b;
}

#endif
View Code
#include <iostream>
#include <string>
#include "Operator.h"

using namespace std;


int main()
{
    Operator<int> op1;
    
    cout << op1.add(1, 2) << endl;
    cout << op1.multiply(4, 5) << endl;
    cout << op1.minus(5, 6) << endl;
    cout << op1.divide(10, 5) << endl;
    
    return 0;
}
View Code

多参类模板:定义任意多个不同类型的参数模板

template < typename T1, typename T2 >  // 
class Test     // 多参类模板名
{
public:
    void function(T1 a, T2 b)  // 多参类模板的功能
    {    }
};

Test<int,int> t;  // 用类模板Test定义一个参数类型为int和int的类t。必须指定参数的类型。

类模板的特化:类模板的特殊形式。将一个类模板分开为不同的情况来实现。本质还同一个模板,

部分特化:特定规则约束类型参数

template < typename T> //
class Test <T,T>   // 使用Test类模板定义类时参数类型相同,则用部分特化模板
{
public:
    void function(T a, T b)  // 
    {  }
};

完全特化:完全显示指定类型参数

template < >  // 没有泛指参数
class Test <int,int>   // 使用Test类模板定义类时指定了类参数为int,int。则使用完全特化模板
{
public:
    void function(int a, int b)  // 
    {  }
};

 编译器根据参数来判断使用哪种模板

#include <iostream>
#include <string>

using namespace std;

template
< typename T1, typename T2 >  // 将模板分开为不同的情况来实现。
class Test
{
public:
    void function(T1 a, T2 b)
    { /* do something */ }
};

template
< typename T1, typename T2 >
class Test < T1*, T2* >      // 关于指针的特化实现
{
public:
    void function(T1* a, T2* b)
    { /* do something */ }
};

template
< typename T >
class Test < T, T >    // 当 Test 类模板的两个类型参数完全相同时,使用这个实现
{
public:
    void function(T a, T b)
    {  /* do something */ }
    void function_1()
    {
        /* do something */
    }
};

template
<  >
class Test < void*, void* >    // 当 T1 == void* 并且 T2 == void* 时
{
public:
    void function(void* a, void* b)
    {  /* do something */ }
};

int main()
{  
    Test<int, float> t1;    // 使用模板 Test
    Test<long, long> t2;    // 使用模板 Test < T, T >
    Test<void*, void*> t3;     // 使用模板 Test < void*, void* >
    Test<int*, double*> t4; // 使用模板 Test < T1*, T2* >
    return 0;
}

 特化:统一的方式使用类模板和特化类

 重定义:一个类模板和一个新的类

原文地址:https://www.cnblogs.com/zsy12138/p/10858766.html