1. 函数与类模版的定义

(1)函数模版

如果重载的函数,其解决问题的逻辑是一致的、函数体语句相同,只是处理的数据类型不同,那么写多个相同的函数体,是重复劳动,而且还可能因为代码的冗余造成不一致性。这时就可以用使用函数模版来解决。(例:求绝对值函数的模版)

#include <iostream>
using namespace std;
template<typename T>
T abs(T x) {
        return x < 0? -x : x;
}
int main() {
        int n = -5;
        double d = -5.5;
        cout << abs(n) << endl;
        cout << abs(d) << endl;
          return 0;

(2)类模板

使用类模板使用户可以为类声明一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值,能取任意类型(包括基本类型的和用户自定义类型)。

//类似于函数形参可有默认实参,函数/类模板可有默认模板实参:
template <typename T = double>//设置默认实参
class Point{
public:
          Point(T _x = 0, T _y = 0): x(_x), y(_y){}
private:
             T x;
             T y;
};
//使用模板:
Point<int> point();          给定模板参数int,定义整数点对象(0, 0)
//
Point<> point();         //模板参数列表<>为空,默认double类型初始化

2. 动态数组类模版程序

#ifndef ARRAY_H
#define ARRAY_H
#include <cassert>
template <class T>           // 数组类模板定义
class Array {
private:
          T* list;                //  用于存放动态分配的数组内存首地址
          int size;                            //数组大小(元素个数)
public:
          Array(int sz = 50);                构造函数
//
          Array(const Array<T> &a);       //拷贝构造函数
          ~Array();                       //析构函数
          Array<T> & operator = (const Array<T> &rhs);           重载"=“
//
          T & operator [] (int i);                //  重载"[]”
          const T & operator [] (int i) const;
          operator T * ();                       //   重载到T*类型的转换
          operator const T * () const;
        int getSize() const;                    //取数组的大小
        void resize(int sz);                    //修改数组的大小
};
template <class T>
Array<T>::Array(int sz) {// 构造函数
        assert(sz >= 0);         为数组大小(元素个数),应当非负
//sz
        size = sz;        // 将元素个数赋值给变量size
        list = new T [size];          //动态分配size个T类型的元素空间
}
template <class T>
Array<T>::~Array() { //  析构函数
        delete [] list;
}
//  复制构造函数
template <class T>
Array<T>::Array(const Array<T> &a) {
        size = a.size;           从对象x取得数组大小,并赋值给当前对象的成员
//
        //为对象申请内存并进行出错检查
        list = new T[size];            // 动态分配n个T类型的元素空间
        for (int i = 0; i < size; i++)     //从对象X复制数组元素到本对象
                list[i] = a.list[i];
}
//  重载"="运算符,将对象rhs赋值给本对象。实现对象之间的整体赋值
template <class T>
Array<T> &Array<T>::operator = (const Array<T>& rhs) {
        if (&rhs != this) {
//  如果本对象中数组大小与rhs不同,则删除数组原有内存,然后重新分配
                if (size != rhs.size) {
                          delete [] list;             删除数组原有内存
//
                          size = rhs.size;           //设置本对象的数组大小
                          list = new T[size];           //重新分配n个元素的内存
                }
                //  从对象X复制数组元素到本对象
                for (int i = 0; i < size; i++)
                          list[i] = rhs.list[i];
        }
        return *this;           返回当前对象的引用
//
}
//重载下标运算符,实现与普通数组一样通过下标访问元素
//并且具有越界检查功能
template <class T>
T &Array<T>::operator[] (int n) {
        assert(n >= 0 && n < size);          // 检查下标是否越界
        return list[n];                          //返回下标为n的数组元素
}
template <class T>
const T &Array<T>::operator[] (int n) const {
         assert(n >= 0 && n < size);           // 检查下标是否越界
         return list[n];                           //返回下标为n的数组元素
}
//  重载指针转换运算符,将Array类的对象名转换为T类型的指针
template <class T>
Array<T>::operator T * () {
         return list;                           //  返回当前对象中私有数组的首地址
}
template <class T>
Array<T>::operator const T * () const {
         return list;          返回当前对象中私有数组的首地址
//
}
//  取当前数组的大小
template <class T>
int Array<T>::getSize() const {
         return size;
}
//   将数组大小修改为sz
template <class T>
void Array<T>::resize(int sz) {
         assert(sz >= 0);          // 检查sz是否非负
         if (sz == size)           //如果指定的大小与原有大小一样,什么也不做
                return;
         T* newList = new T [sz];                    //申请新的数组内存
         int n = (sz < size) ? sz : size;            //将sz与size中较小的一个赋值给n
          将原有数组中前n个元素复制到新数组中
//
         for (int i = 0; i < n; i++)
                newList[i] = list[i]            delete[] list;         //删除
原数组
         list = newList;                  //   使list指向新数组
         size = sz;                 //  更新size
}
#endif   //ARRAY_H