一.概述

二.函数模板

1.概述

(1)介绍

C++的函数模板在一定程度上类似于Java的泛型,可以类比学习

编译次数:函数模板会编译两次,一次是对函数模板本身的编译,一次是在调用函数模板时,会将T的类型具体化,然后再编译一次

**函数模板的目标:**函数模板是为了实现泛型,可以减轻编程的工作量,增强函数的重用性

**参数类型的来源:**在调用函数模板时

  • 如果没有显示的指定函数模板的类型,编译器会根据传入的参数自动推导类型,并对模板中类型的代号进行替换
  • 如果显示制定了函数模板的类型,那编译器就会直接以指定的类型替换函数模板中的类型

(2)注意事项

  • 函数模板和普通函数都识别时,编译器默认会优先选择普通函数

    因为可以减少编译的次数

  • 函数模板和普通函数都识别时,可以通过显示指定使用函数模板,使编译器选择函数模板

    在函数名后附加<>,可以指定使用函数模板。例如:Test<>(1,2)

  • 函数模板自动类型推导时,不能对函数的参数进行自动类型转换

    • 显示指定模板类型时,是可以进行自动类型转换的,即小类型to大类型

      Test(10,'b');//里面的b字符会被替换成ASCII码-98

2.格式

(1)参数

下面的T是类型占位符,可以任意取的,且该数据类型只在函数模板内有效

  • template :函数模板的定义
    • typename T 用于告知编译器T是一个数据类型
  • T parameter1, T parameter2:函数的参数列表
    • 用函数模板定义的T作为参数的数据类型

(2)格式:

template 返回值类型 函数名才是真正的函数模板,也只有他才能代表函数模板

template //可以声明一个类型,也可以声明多个类型 返回值类型 函数名(T parameter1, V parameter2) { // 函数实现 }

(3)示例

下面交换元素信息的函数模板,不论传入什么类型都可以调用

#include using namespace std; /*函数模板*/ //template声明的类型只在函数模板内有效 template void exchange(T data1,T data2){ T temp = data1; data1 = data2; data2 = temp; cout << "data1:" << data1 << " data2: " << data2 << endl; } int main(){ /*调用函数模板*/ //编译器自动类型推导 exchange(10,20); exchange('a','b'); //显示指定模板的数据类型 exchange(30,40); } /* data1:20 data2: 10 data1:b data2: a data1:40 data2: 30 */

3.函数模板重载

① 概述

重载的规则和普通函数重载一致,让函数参数、个数、顺序不同即可

② 示例
template void exchange(T data){ cout << data << endl; } /*重载函数模板*/ template void exchange(T data1,T data2){ T temp = data1; data1 = data2; data2 = temp; cout << "data1:" << data1 << " data2: " << data2 << endl; }

4.局限性

(1)概述

当函数模板推出的类型是数组或则是其它自定义类型时,可能会运算符不识别,此时,可以采取运算符重载具体化函数模板的形式进行解决

(2)运算符重载

① 概述

根据编辑器的提示,重写不识别的运算符即可

对不识别的运算符进行重载,使其能够正常运行即可

image-20240317150301358
image-20240317150301358
② 示例
#include using namespace std; class Data{ public: int data; public: Data(){ this->data = 0; } Data(int x){ this ->data =x; } }; /*函数模板*/ //template声明的类型只在函数模板内有效 template void exchange(T data1,T data2){ T temp = data1; data1 = data2; data2 = temp; cout << "data1:" << data1 << " data2: " << data2 << endl; } /*重写报异常的<<运算符*/ ostream & operator<<(ostream & out,Data obj){ out << obj.data; return out; } int main(){ Data data1(1); Data data2(2); exchange(data1,data2); }

(3)具体化函数模板

① 概述

概述: 就是具体指明函数模板中的泛型是什么数据类型

② 格式

格式: 具体化函数模板的时候,template后的<> 不用指定内容

template<> 数据类型 函数名<具体化的类型>(数据类型 对象名){ }

例子:

template<> void exchange(Data data1,Data data2){ Data temp = data1; data1 = data2; data2 = temp; cout << "data1:" << data1.data << " data2: " << data2.data << endl; }
③ 示例
#include using namespace std; class Data{ public: int data; public: Data(){ this->data = 0; } Data(int x){ this ->data =x; } }; /*函数模板*/ //template声明的类型只在函数模板内有效 template void exchange(T data1,T data2){ T temp = data1; data1 = data2; data2 = temp; cout << "data1:" << data1 << " data2: " << data2 << endl; } /*具体化函数模板*/ template<> void exchange(Data data1,Data data2){ Data temp = data1; data1 = data2; data2 = temp; cout << "data1:" << data1.data << " data2: " << data2.data << endl; } int main(){ Data data1(1); Data data2(2); exchange(data1,data2); }

三.类模板

1.概述

简述: 类模板是一种特殊类型的类,它允许程序员编写一个通用的类定义,这个类可以与多种不同的数据类型一起工作。通过使用模板,我们可以编写一个代码,它可以在多种数据类型上工作,而无需为每种数据类型重写代码

注意事项:

  • 使用类模板必须显式的指定类模板的数据类型

2.格式

使用template关键字声明的类型用于定义类内的成员

(1)简述

类模板的声明使用template关键字,后面跟着尖括号中的模板参数列表。模板参数列表可以包含一个或多个类型参数。

(2)格式

类模板的是template class MyClass这一个整体,无论是声明友元还是类外实现类模板内函数,都要以其作为函数名

定义:

template class MyClass { public: T value; MyClass(T val) : value(val) {} void printValue() { std::cout << "Value: " << value << std::endl; } };

使用类模板创建对象:

创建类模板对象时,要在<> 显式制定类型

MyClass ob(value);

(3)示例

定义了一个名为Data的类模板,并使用类模板创建了对象0b1,并调用了类模板的showData方法

#include using namespace std; template class Data{ public: T1 a; T2 b; public: Data(){} Data(T1 a,T2 b){ this -> a = a; this -> b = b; } void showData(){ cout << a << " " << b < ob1(10,20); ob1.showDat
最后修改:2024 年 03 月 18 日
如果觉得我的文章对你有用,请随意赞赏