【C++标准模板库笔记1】C++的模板技术
来源:互联网 发布:西安传智java培训 编辑:程序博客网 时间:2024/05/16 18:22
/************************************************************************************************************************文件说明: C++的模板技术开发环境: Win10+VS2013+STL时间地点: 陕西师范大学 文津楼 2017.7.26作 者: 九 月*************************************************************************************************************************/
(一)C++模板技术的简介
1)C++模板是一种十分重要的技术,STL标准模板库的一般算法和容器就是通过模板编程实现的,并以函数模板和类模板提供出来。
2)顾名思义,模板的作用就在于定制函数和类。只要将数据类型传递给函数模板和类模板,就可以生成特定数据类型下的函数和类,实现了数据类型不同、但是程序逻辑完全相同的代码重用,减轻了编程的工作量,并可使大量常用的功能代码完整而简洁的纳入到标准库中,极大的改善了C++的变成环境。
3)模板纯粹是为了将预处理宏推广到C++而来,不同于宏使用一套"指令开头用#,指令结尾不适用分号,标识符定义不适用类型"的备受争议的语法。
4)模板的定义可以跟函数和类的定义融合在一起,完全是在它们的基础上添加一些新的语法,因此又称为函数模板和类模板,表明模板的语法仿照了熟悉的函数和类的语法,只是数据类型需要用关键字templates声明为泛型。
(二)函数模板
(1)函数模板的概念
假设要编写一个函数对两个参数求和。实际编程中,我们可能希望定义几个这样的函数,每一个可以对一种给定类型的值求和,那么可能自然会想到函数的重载。例如:
int add(int a, int b){return a + b;}double add(double a, double b){return a + b;}char add(char a, char b){return a + b;}这些函数几乎相同,每个函数的函数体是相同的,功能也是相同的,它们之间唯一的不同在于形参的类型和函数返回值的类型。
事实上,在具体编写上述代码时,我们必须手工的书写所有的代码,所以会使用复制、粘贴、修改的编辑功能得到另一种类型的求和函数。如果每种类型都需要重复函数的函数体,不仅麻烦,而且容易出错。更重要的是,需要事先知道可能会支持的所有类型的组合情况。如果希望将函数用于未知类型,这种方法就是有问题的。
C++有模板(template)机制,可以使用函数模板解决上述存在的问题。函数模板(function template)是一个独立于类型的函数,可作为一种模式,产生函数的特定类型版本。
使用函数模板可以设计通用型的函数,这些函数与类型无关,并且只在需要时自动实例化,从而形成"批量型"的编程方式。
(2)函数模板的定义和使用
(1)函数模板的定义
函数模板定义的语法形式为:
template<模板形参表>返回值类型 函数名(形式参数列表){函数体}可以约定,第1行称为模板定义,其后称为模板函数,与函数定义语法类似。
模板定义以关键字template开始,后接模板形参表。模板形参表(template parameter list)是用一对尖括号<>括起来的一个或多个模板形参的列表,不允许为空,形参之间以逗号分隔,其形式有两种:
第一种形式如下所示: typename 类型参数名1,typename 类型参数名2............第二种形式如下所示: class 类型参数名1,class 类型参数名2...................在函数模板形参表中,typename和class具有相同含义,可以互换使用,或者两个关键字都可以在同一模板形参表中使用。
不过由于C++中class关键字往往容易与类联系在一起,所以使用关键字typename比使用class更直观,typename可以更加直观的反映出后面的名字是一个类型名。
模板定义的后面是函数定义,在函数定义中,可以使用模板形参表中的类型参数。例如:
template<typename T> add(T a, T b){ return a + b;}函数模板定义语法的含义是一个通用型函数,这个函数类型和形参类型没有具体的指定,而是一个类型记号表示,类型记号由编译器根据所用的函数而确定,这种通用型函数成为函数模板。
使用函数模板时,编译器会推断那个(或那些)模板实参绑定到模板形参上,一旦编译器确定了实际的模板实参,将实例化函数模板。即编译器将确定用什么类型代替每个类型形参,以及用什么值代替每个非类型形参,推导出实际的模板实参后,编译器使用类型实参代替相应的模板形参产生并编译该版本的函数。这里,编译器承担了我们使用的每种类型编写的重复工作,我们不用在机械的复制、黏贴、修改等手工书写了。
(2)函数模板的使用
可以像普通函数那样使用模板函数调用。
#include<iostream>using namespace std;template<typename T>T add(T a, T b){return a + b;}int main(){std::cout << "int_add = " << add(10,20)<< std::endl;std::cout << "double_add = " << add(10.2, 20.5) << std::endl;std::cout << "char_add = " << add(10, 20) << std::endl;std::system("pause");return 0;}
(三)类模板
(1)类模板的简介
类似于函数模板的做法,类模板对数据成员的数据类型和成员函数的参数类型进行泛化。如下是类模板的一个基本定义形式,关键字template说明类型T1~Tn是模本类型,成员函数可在类模板的声明中定义。
template<class T1,class T2,.....,class Tn> class 类名{//成员声明或定义;};template<class T1, class T2, ....., class Tn> 返回值 类名<T1,T2, ....., Tn>::成员函数1{//函数定义}template<class T1, class T2, ....., class Tn> 返回值 类名<T1, T2, ....., Tn>::成员函数2{//函数定义}注意:
不同于非模板代码的组织方式,函数模板和类模板的声明和定义代码,一般都编写在.h头文件中,以免由于为具现而提示编译链接错误。
下面给出一个类模板表示平面上点的示例:
template<class T> //【0】类模板定义class Point //【1】Point不是类名是模板名{public:Point::x(0), y(0) {} //【2】默认构造函数Point(const T a, const T b) :(x)(a), y(b) {} //【3】带参数的构造函数void Set(const T a, const T b);void Display();private:T x;T y;};
- 【C++标准模板库笔记1】C++的模板技术
- C++:标准模板库(STL)
- C++:标准模板库vector
- C++:标准模板库map
- C++:标准模板库string
- C++:标准模板库Sort
- C++STL标准模板库
- 标准C的.h文件的模板
- 21天学通C++--阅读笔记6(模板、标准模板库)
- C++:STL(标准模板库)
- C++_标准模板库(STL)
- stdlib 标准C 模板库函数
- C/C++_log2000_函数模板与类模板笔记1
- C++:标准库和标准模板库STL概述
- C++ STL和标准模板库及C标准库的关系
- C/C++学习笔记(十)标准模板库STL和string
- C++中的标准模板库STL及容器
- C++,VC++,MFC,STL(standard template library,标准模板库)
- 阶乘之和--NYOJ---91(贪心)
- CentOS 安装WildFly Jboss10
- SQL加强(一)概念
- HDU 6039 Gear Up(2017 Multi-University Training Contest 1)
- 算法题:输入aaaabbbcccccc输出a4b3c6。
- 【C++标准模板库笔记1】C++的模板技术
- C++三大特性——多态
- thinkphp3.2 后台获取app前端多个图片上传及参数 的接口写法(upload()函数)
- 关于Javaemail发送邮件时遇到的问题
- selenium server运行报错
- mybatis入门基础(七)----延迟加载
- java排序算法
- Alpine Linux 使用简介
- Linux学习笔记一