C++_25_函数模板和类模板 - 重写版

发布时间 2023-12-04 00:10:59作者: 尘落曦枫

模板:

  在C++中允许函数重载,但函数重载每次都必须完全对上参数的顺序,类型和数量。
  所以C++提供了另一种代码重用机制——“模板”,可以作为同一种类型函数的统一调用接口。

    模板机制下可划分:1、函数模板
                     2、类模板

  模板的语法 

template <typename T>                 //单个数据类型
template <typename T,typename P> //多个数据类型

 

    template    关键字,表示后面跟的是模板的声明
    typename     关键字表示后面接的是模板中声明的数据类型,可以用class替代
    T        自定义变量数据类型,表示未知的数据类型
    模板实质上是对函数中数据类型的替换
  注意事项
    (1)模板函数中的参数类型、顺序和个数都需要与调用时的函数保持一致。
    (2)如果需要强制指定传入的参数类型,可以使用 函数名<类型名>(参数)。
    (3)对于模板函数而言,如果没有指明参数类型,是无法运行的。如果运行,需要加上<类型名>

        int x = 10; 
        int y = 20;
                  //调用函数myswap函数实参a,b 必须与模板函数中的形参a,b保持一致
        myswap<int>(x, y);   //1 函数模板 显示类型 调用   
        myswap(x, y);        //2 自动类型 推导  x,y类型已经致命,系统默认自行补全,效果一样

 

 

函数模板:

  函数模板:就是建立一个通用函数,函数类型和形参类型用虚拟的类型来代表的函数。
  凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可。
  在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。

  函数模板与普通函数的区别
      1、普通函数是存在隐式类型转换。(传参强制转换,不需要特殊声明相纸转换,默认隐藏)
      2、函数模板不存在隐式类型转换,必须使用 <类型名> 的方式确定数据类型。(必须显示声明)

  函数模板与普通函数的调用机制
    (1)当函数模板和普通函数同时完全满足调用需求,优先使用普通函数运行程序。
    (2)如果普通函数在满足调用时需要进行隐式类型转换,而函数模板不用,则优先调用函数模板
    (3)如果调用不符合函数模板的要求,则按照普通函数隐式转换来运行。
    (4)当普通函数完全符合调用标准的情况下,仍然使用函数模板,则加上 <>(2和4相互印证)

  函数模板的局限性
       当函数模板中的数据类型是结构体或者类时,需要去重载运算符或重载函数。



 

类模板

template <class T1,class T2>
class 类名{
   T1   成员属性1
   T2   成员属性2
};

  定义对象 

 类名   <类型1,类型2>对象名(参数)

  定义模板类时,可以为模板类提供默认参数类型,
    当存在默认参数类型时,定义的对象可以直接使用<>来定义 
  

  类模板中函数定义的时机
    类模板中的函数是在程序运行时才确定的,在编译过程中没有固定下来。

  类模板在函数中的传参
    传参方式一共有3种
      (1)在参数中明确模板的数据类型
      (2)把函数也设置为模板函数
      (3)把传入的参数设置为模板类

   类模板的继承
    基类为类模板的时候,派生出的子类必须对基类的数据类型有明确的规定,
      否则派生类也必须写成类模板
  

  类模板成员函数的类外定义和多文件编译
  

  语法格式

返回值  类名 <类型> :: 函数名(参数)

    模板的多文件编译,它的函数定义和函数声明应该放在同一个文件里面,
      并且放在一起的时候,文件后缀名是.hpp。(hpp = .h + .cpp) 

  类模板的友元
    (1)在类内定义友元函数。
    (2)在类外定义友元函数,必须额外再template一个模板,把全局函数当成模板函数。