当前位置: 首页 > news >正文

c++模板入门

c++系列模板入门


文章目录

  • c++系列模板入门
  • 一、模板概念引入
  • 二、函数模板
    • 2.1、函数模板的概念
    • 2.2、函数模板的定义格式
    • 2.3、函数模板的使用
  • 三、类模板
    • 1.1、什么是类模板
    • 1.2、类模板的定义格式
    • 1.3、类模板于函数模板的区别


一、模板概念引入

在程序设计中我们经常需要对两个数据进行交换,对于不同的数据类型,我们就需要重载不的函数。

void Swap(int& left, int& right){int temp = left;left = right;right = temp;} 
void Swap(double& left, double& right){double temp = left;left = right;right = temp;}

问:面对这些逻辑相同,仅是类型不同的程序,我们该如何更好的实现他们呢?

答:如果有一个模具,通过给这个模具中填充不同材料(类型),来获得不同材料的铸件(生成具体类型的代码),那我们将会方便很多,为完成这一问题C++产生了泛型编程的思想。
泛型编程:允许函数和数据结构使用任何数据类型,而不需要为每种数据类型编写重复的代码。模板是泛型编程的基础。
模板——是一段带有类型参数的程序代码,可以通过给这些参数提供一些类型来得到针对不同类型的具体代码。

二、函数模板

2.1、函数模板的概念

函数模板并不是一个可以直接使用的函数,它实际上是定义一个通用函数,它所用到的数据的类型(包括返回值类型、形参类型、局部变量类型)均被作为参数:不指定具体类型,而是用一个虚拟 的类型来代替(实际上是用一个标识符来占位)。凡是函数体相同的函数都可以用这个模板来代替,在函数调用时根据传入的实参来逆推出真正的类型(逆推过程由编译器来完成),从而来实现代码的复用。这个通用函数就称为函数模板(函数模板不是一个实在的函数,编译器不能为其生成可执行代码)。

2.2、函数模板的定义格式

template<class / typename T1,......,class / typename Tn> typename用来定义模板参数关键字,也可以使用class,在这里他们两个的作用并无区别,T1....Tn均为类型占位符。

 template<typename T>//简单函数模板void Swap( T& left,  T& right){T temp = left;left = right;right = temp;}

2.3、函数模板的使用

以两数相加函数为例,我们在进行不同类型对象间的数据相加问题时,就不需要重写多个函数 例:

template<class T1>
T1 add(T1 x,T1 y)//T1类型占位符,编译器推演出合适的类型将他替换
{return x + y;
}
int main()
{int a1 = 1;int a2 = 2;double a3 = 1.1;double a4 = 2.1;cout << add(a1, a2) << endl;cout << add(a3, a4) << endl;return 0;

运行结果:

在这里插入图片描述
在使用函数模板时,我们只需要传递实参,编译器会自动推演出合适的类型。
在这里插入图片描述
可以看到,即使存在模板还是可以定义,具体的函数的,编译器在生成函数之前,首先会去,局部、全局找是否有合适的函数,如果有则调用已存在的,否则生成函数(这里double类型就没有合适的,所以调用生成函数)。
在这里插入图片描述
在这里插入图片描述
通过上面两张图我们可看到,我将模板屏蔽后代码是可以执行的,这是因为,我们自己定义的函数,支持隐式类型转换(从打印结果可以看到,从在数据丢失问题),当我们,将自定义函数屏蔽后,成序出错,这是因为,我们只声明了一个类型占位符,编译不知道将他推演成什么类型(间接反映出,编译器生成的函数,不支持隐式类型转换)。

对于这个问题,我们有三种方法解决:
1.在传递实参时,进行显示类型转换

   cout << add(a1,(int) a4) << endl;

2.在原模板上,增加一个模板参数

template<class T1,class T2>
T1 add(T1 x,T2 y){}//这里函数体省略了

3.模板显示实例化

   cout << add<int>(a1, a4) << endl;

具体改变大家可以用代码跑一下

三、类模板

1.1、什么是类模板

类模板是一种用来生成类定义的模板,其中可以包含一个或多个类型参数。这些类型参数可以在定义类的时候替换为任意类型,从而使得我们能够创建适用于多种数据类型的通用类定义。类模板的定义使用 template < class T> 或 template< typename T> 来声明一个类型参数(可以声明多个)。

1.2、类模板的定义格式

template<class T1, class T2, ..., class Tn> 
class 类模板名
{// 类内成员定义
}; 

我们以这个简单的线性表为例,进行讲解

template<class T>
class Vector
{
public:Vector(size_t capacity = 10): _pData(new T[capacity]),_size(0),_capacity(capacity){}// 使用析构函数演示:在类中声明,在类外定义。~Vector();void PushBack(const T& data)void PopBack()size_t Size() { return _size; }T& operator[](size_t pos){assert(pos < _size);return _pData[pos];}
private:T* _pData;size_t _size;size_t _capacity;
};
// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表
template <class T>
Vector<T>::~Vector()
{if (_pData)delete[] _pData;_size = _capacity = 0;
}

在对类模板进行定义时,类的成员函数一样可以使用,模板参数精选模板定义。

1.3、类模板于函数模板的区别

类模板不同于函数模板,它没有自动类型推导的使用方式,类模板在使用时,只能使用显示定义的方式 例:

//使用类模板创建对象Vector<int> v1;vector<double> v2;

这里我们要知道,类名(vector)并不是所创建对象的类型,只有对象被实力出来,它才具有类型(vector< int>、vector< double>).

类模板可以有,默认参数类型例:

template<class T1, class T2, ..., class Tn=int>//默认参数类型 
class 类模板名
{// 类内成员定义
}; 

这里同定义函数时,使用缺省参数,原理相同。


http://www.mrgr.cn/news/65074.html

相关文章:

  • 托福学科单词:气候类型与植物分布
  • 探索Python新境界:Buzhug库的神秘面纱
  • 嵌入式linux跨平台基于mongoose的TCP C++类的源码
  • SVD求解ICP旋转矩阵不正确处理
  • Android Studio各种历史版本
  • Rust 力扣 - 54. 螺旋矩阵
  • Golang--函数、包、defer、系统函数、内置函数
  • 线性代数:Matrix2x2和Matrix3x3
  • 数据结构-二叉树中的递归
  • DBeaver的sql查询结果突然不见了,怎么办?
  • 练习题 - Scrapy爬虫框架 Cookies 本地终端数据
  • 每一次放纵自己,意味着比以前更弱小(8)
  • 数据结构-链表【chapter1】【c语言版】
  • Unity Job System详解(3)——NativeList源码分析
  • Pandas进行数据查看与检查
  • 交换排序(冒泡/快排)
  • GPU架构概述
  • 高级java每日一道面试题-2024年10月28日-JVM篇-详细介绍一下CMD垃圾回收器?
  • Vue-Router详解【学习Vue-Router看这一篇就够了!!!】
  • RK3568平台开发系列讲解(SPI篇)SPI 控制器驱动分析
  • 如何使用Get进行状态管理
  • ts:使用typeof运算符输出各对象的类型
  • Linux 信号
  • 算法——递推
  • 各地级市能源消耗量数据-基于灯光数据的反演(2000-2022年)
  • 虚拟内存与物理内存之间的映射关系