STL 函数模板,类模板

13 篇文章 0 订阅

模板

为什么使用模板

  1. C/C++是一种静态类型语言(预处理->汇编->编译->链接),好处是速度快,缺点是实现通用代码麻烦,例如:实现支持所有类型的快速排序
  2. 借助函数重载实现通用代码,好处是实现简单,但代码段会增加
  3. 借助宏函数来实现通用代码,类型检查不严格
  4. 借助回调函数实现通用代码,使用麻烦
  5. 由于以上原因,C++之父在C++中实现了模板技术,让C++能够支持泛型编程

函数模板

  1. 函数模板的定义

    template <typename 类型参数1,typename 类型参数2...>
    类型参数1 函数名(类型参数2 参数名)
    {
        return 返回值;
    }
    
    template <typename T>
    T find (T* arr,size_t len)
    {
        return val
    }
    
    • 可以用任何标识符当类型参数名,但使用T是约定俗成
#include <iostream>
using namespace std;
template <typename T>
T Max(T val1,T val2)
{
    return val1 > val2 ? val1:val2;
}
int main()
{
    cout << Max<char>('a','c') << endl;//手动实例化
    cout << Max<>(5,2) << endl;
    cout << Max(2.44,8.99) << endl;
}
  1. 函数模板的使用
  • C++的编译器并不是把模板编译成一个任何类型的单一实体,而是根据模板的使用者的参数产生不同的实体
  • 根据具体类型代替模板参数生成函数实体的过程叫做实例化
  • 模板是在使用时才实例化,可以自动实例化也可以手动实例化(在函数调用时函数名与小括号之间加<类型参数>)
  • 每个函数模板都会进行二次编译,第一次编译在实例化之前,检查模板代码本身是否正确,第二次在实例化的过程中,结合所使用的类型,再次检查模板代码,是否所有的代码都有效
  • 注意 第二次编译才会生成二进制指令,每一次编译仅仅是在编译器内部生成一个用于描述模板的数据结构
  1. 函数模板的隐式推断
  • 函数模板虽然可以手动实例化,但使用麻烦,一般根据参数类型进行隐式推断模板的参数
  • 注意 不能隐式推断的三种情况:
    1. 函数参数与模板类型参数没有关系
    2. 不允许隐式类型转换
    3. 返回值类型不能隐式转换
  1. 函数模板与默认形参之间互相冲突
  2. 普通函数与模板函数构成重载,编译器会优先调用普通函数,如果实现一个与模板函数功能一致的普通函数,那么这叫做模板函数的特化
  • 注意 一般字符串类型char* 类型都需要特化

练习1: 实现冒泡,插入,快速,归并,堆排序算法的函数模板

类模板

  1. 类模板的定义
template <typename M,typename R,typename A,typename O>
class Test
{
public:
    M val;
    Test(A a)
    {
        O var;
    }

    R func(void)
    {

    }
};
  1. 类模板的使用
    • 注意 类模板的参数不支持隐式推断,必须显式指定类型参数
      • 类名<类型...> 对象(初始化参数);
    • 类模板分为两步进行实例化:
      • 编译器:编译器将类模板实例化类,生成类对象创建指令
      • 运行期:处理器执行类对象创建指令,将类实例化为对象
    • 类模板也是一种静态多态
    • 类模板中,只有那些被调用的成员函数才实例化,即产生二进制指令(调用谁实例化谁)
  2. 类模板的静态成员
    • 静态成员需要在类外定义,但与普通类的定义不同的
      • template <typename ...> 类型 类名<...>::成员名;
  3. 递归实例化
    • 类模板的参数可以是任何类型,只要该类型提供类模板所需的功能
    • 类模板的实例化已经是一个有效的类型了,因此它也可以当作类模板的参数,这种叫递归实例化
    • Vector<Vector<int>>//二维数组
    • Test<Test<int>>

练习2 实现一个顺序栈的模板类

  1. 类的局部特化

    • 当类的某个成员函数不能通用,需要对特殊类型(char*)实现一个特殊版本,这叫做类的局部特化
    template<> 返回值类型 类名<类型>::函数名(参数)
    {
    };
    
    • 注意 在类外实现
  2. 全类特化

    • 当需要针对某种类型对类全部实现一个特殊版本,这叫类的全特化
    template<> 类名<类型>
    {
    };
    
  3. 类模板的缺省值

    • 类模板类型参数可以设置默认类型,规则与函数的默认形参基本一致(设置缺省值类型靠右)
    • 后面的类型参数可以使用前面的类型,但前面的不能使用后面的
  4. 普通数据也可以作为模板的参数

    template <typename T,类型 B>
    
    • 给类模板一个数据,在类中就可以像使用宏名一样使用参数
    • 注意 实例化类时提供的数据必须是常量

    作业 实现list模板类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值