C++的函数模板与类模板

时间:2021-06-22 19:03:11

1.函数模板

函数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。

1.1函数模板的定义:

template<类型形式参数表>
返回类型 函数名(形式参数表)
{
… //函数体
}

template // or class T
void Swap(T &a, T &b);
或者:
template //
void Swap(T &a, T &b);

(I):一个函数模板可以有多个类型参数

template<class T1, class T2>
void print(T1 arg1, T2 arg2){
    //函数体
}

(II):函数模板的类型参数可以用于函数体模板的局部变量声明

template<class T1, class T2>
void print(T1 arg1, T2 arg2){
        T1 locVar=arg1;
        //函数体
}

1.2实例

// funtemp.cpp -- using a function template
#include <iostream>
// function template prototype
template <typename T>  // or class T
void Swap(T &a, T &b);

int main()
{
    using namespace std;
    int i = 10;
    int j = 20;
    cout << "i, j = " << i << ", " << j << ".\n";
    cout << "Using compiler-generated int swapper:\n";
    Swap(i, j);  // generates void Swap(int &, int &)
    cout << "Now i, j = " << i << ", " << j << ".\n";

    double x = 24.5;
    double y = 81.7;
    cout << "x, y = " << x << ", " << y << ".\n";
    cout << "Using compiler-generated double swapper:\n";
    Swap(x, y);  // generates void Swap(double &, double &)
    cout << "Now x, y = " << x << ", " << y << ".\n";
    // cin.get();
    system("pause");
    return 0;
}

// function template definition
template <typename T>  // or class T
void Swap(T &a, T &b)
{
    T temp;   // temp a variable of type T
    temp = a;
    a = b;
    b = temp;
}

2.函数模板的重载

同一函数名,类型参数的数量不同。
需要对多个不同类型使用同一种算法的函数时,重载函数模板。被重载的模板的函数的特征标(模板类型参数列表)必须不同。

2.1实例

// twotemps.cpp -- using overloaded template functions
#include <iostream>

template <typename T>     // original template
void Swap(T &a, T &b);

template <typename T>     // new template
void Swap(T *a, T *b, int n);

void Show(int a[]);
const int Lim = 8;
int main()
{
    using namespace std;
    int i = 10, j = 20;
    cout << "i, j = " << i << ", " << j << ".\n";
    cout << "Using compiler-generated int swapper:\n";
    Swap(i, j);              // matches original template
    cout << "Now i, j = " << i << ", " << j << ".\n";

    int d1[Lim] = { 0,7,0,4,1,7,7,6 };
    int d2[Lim] = { 0,7,2,0,1,9,6,9 };
    cout << "Original arrays:\n";
    cout << "d1[8]: " << endl;
    Show(d1);
    cout << "d2[8]: " << endl;
    Show(d2);
    Swap(d1, d2, Lim);        // matches new template
    cout << "After Swapping arrays:\n";
    cout << "d1[8]: " << endl;
    Show(d1);
    cout << "d2[8]: " << endl;
    Show(d2);
    // cin.get();
    return 0;
}
template <typename T>
void Swap(T &a, T &b)
{
    T temp;
    temp = a;
    a = b;
    b = temp;
}

template <typename T>
void Swap(T a[], T b[], int n)
{
    T temp;
    for (int i = 0; i < n; i++)
    {
        temp = a[i];
        a[i] = b[i];
        b[i] = temp;
    }
}
void Show(int a[])
{
    using namespace std;
    for (int i = 0; i < Lim; i++)
        cout << a[i]<<" ";
    cout << endl;
}

运行结果:
C++的函数模板与类模板

3.类模板

I.为了多快好省地定义一批相似的类,可以先定义类模板,然后由类模板生成不同的类(即模板类)。
II.在定义类的时候给它一个或者多个参数,这个/些参数表示不同的数据类型。
III.在调用类模板时,指定参数,由编译系统根据参数提供的数据类型自动产生相应的模板类

3.1类模板的定义

template<class T1, class T2>//一个或者多个类型参数
class MyclassTemplateName{
    //成员函数和成员变量
}

类模板的参数声明中可以包括非类型参数:
非类型参数用来说明类模板中的某些属性,而类型参数则是用来说明类模板中的属性类型,成员服务的参数类型和返回值类型。通常,类模板参数声明中的非类型参数可以提高程序的执行效率。

template<class T1,class T2,int size>
class PairKV{
     //成员函数和成员变量
}

同函数模板一样,类型参数表中的关键字class可以用typename,此处class并不是表示一个类类型,可以用基本数据类型进行实例化。
类模板的成员函数拿到类外定义语法如下:

template<class T1,class T2>
return_valueType MyclassTemplateName<class T1,class T2>::myfunction(参数列表){
    //函数体
}

用类模板定义对象的写法如下:

MyclassTemplateName<真实类型参数表>对象名(构造函数实际参数表);
MyclassTemplateName<真实类型参数表>对象名;  //无参构造函数

3.2实例

#include <iostream>
#include<string>
using namespace std;

//define classTemplate
template<class T1,class T2>
class PairKV {
public:
    T1 key;//index
    T2 value;// value
    PairKV(T1 k, T2 v) :key(k), value(v) {};
};

int main(){
    PairKV<string, int>student("Tom",20 );//实例化一个对象
    cout << student.key << " " << student.value << endl;
    return 0;
}

4.模板类的概念

I.模板类—–为类模板中各类型参数指定了具体的数据类型后,即得到了一个模板类。
(1)编译系统自动用具体的数据类型替换类模板中的类型参数,生成模板类的代码。
(2)为类型参数指定的数据类型不同,得到的模板类不同。也就是说一个类模板可以生成很多种不同的模板类。
II.模板类=实例化的类模板

5.类模板的产生

(1)直接定义
(2)类模板从其他类模板派生
(3)类模板从其他模板类派生
(4)类模板从普通类派生