模板

  • 函数模板:重载的进一步抽象,只需定义一个函数体即可用于所有类型
  • 在C++中,数据的类型也可以通过参数来传递,在函数定义时可以不指明具体的数据类型,当发生函数调用时,编译器可以根据传入的实参自动推断数据类型。这就是类型的参数化
  • 值(Value)和类型(Type)是数据的两个主要特征,它们在C++中都可以被参数化
  • 所谓函数模板,实际上是建立一个通用函数,它所用到的数据的类型(包括返回值类型、形参类型、局部变量类型)可以不具体指定,而是用一个虚拟的类型来代替(实际上是用一个标识符来占位),等发生函数调用时再根据传入的实参来逆推出真正的类型。这个通用函数就称为函数模板(Function Template)
  • typename关键字也可以使用class关键字替代
  • 类模板中定义的类型参数可以用在类声明和类实现中,类模板的目的同样是将数据的类型参数化
  • 一但声明了类模板,就可以将类型参数用于类的成员函数和成员变量了
  • 与函数模板不同的是,类模板在实例化时必须显式地指明数据类型,编译器不能根据给定的数据推演出数据类型
  • C++ 模板也是被迫推出的,最直接的动力来源于对数据结构的封装
  • 数据结构中每份数据的类型无法提前预测,而 C++ 又是强类型的,数据的种类受到了严格的限制
  • STL(Standard Template Library,标准模板库)就是 C++ 对数据结构进行封装后的称呼
  • 并非所有的类型都使用同一种算法,有些特定的类型需要单独处理,为了满足这种需求,C++ 允许对函数模板进行重载
  • 模板(Templet)并不是真正的函数或类,它仅仅是编译器用来生成函数或类的一张“图纸”。模板不会占用内存,最终生成的函数或者类才会占用内存。由模板生成函数或类的过程叫做模板的实例化(Instantiate),相应地,针对某个类型生成的特定版本的函数或类叫做模板的一个实例(Instantiation)
  • 模板也可以看做是编译器的一组指令,它命令编译器生成我们想要的代码
  • 通过类模板创建对象时,一般只需要实例化成员变量和构造函数
  • 通过类模板创建对象时并不会实例化所有的成员函数,只有等到真正调用它们时才会被实例化;如果一个成员函数永远不会被调用,那它就永远不会被实例化
  • 编译是针对单个源文件的,只要有函数声明,编译器就能知道函数调用是否正确;而将函数调用和函数定义对应起来的过程,可以延迟到链接时期。正是有了链接器的存在,函数声明和函数定义的分离才得以实现
  • 程序员惯用的做法是将模板的声明和定义都放到头文件中
  • 模板的实例化是按需进行的,用到哪个类型就生成针对哪个类型的函数或类,不会提前生成过多的代码
  • 模板的实例化是由编译器完成的,而不是由链接器完成的
  • 在实例化过程中需要知道模板的所有细节,包含声明和定义

容器

  • 容器(container)是用于存放数据的类模板
  • 容器都是类模板。它们实例化后就成为容器类。用容器类定义的对象称为容器对象
  • 例如,vector<int>是一个容器类的名字,vector<int> a;就定义了一个容器对象 a
  • 容器分为顺序容器和关联容器
  • 顺序容器有以下三种:可变长动态数组 vector、双端队列 deque、双向链表 list
  • 它们之所以被称为顺序容器,是因为元素在容器中的位置同元素的值无关,即容器不是排序的
  • 关联容器有以下四种:set、multiset、map、multimap
  • 关联容器内的元素是排序的,因此插入元素时不能指定位置
  • 默认情况下,关联容器中的元素是从小到大排序(或按关键字从小到大排序)的
  • 数组是一种类似于vector的数据结构,但数组大小确定,不能随意向其中增加元素
  • vector是使用容器时的首选,它几乎支持所有相关操作,它的主要问题在于元素在内存中是连续存储的,每次执行插入、删除操作时都需要对元素进行移动,当vector很大或其中存储的元素很大时会大大降低代码的性能
  • 如果需要在程序中指向许多数量很多又很大的对象,应该考虑使用list,但list占用空间大,一个list<char>需要12字节,一个vector<char>需要1字节
  • 关联容器支持高效的关键字查找和访问,两个主要的关联容器类型是map和set

迭代器

  • 要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行
  • 迭代器是一个变量,相当于容器和操纵容器的算法之间的中介
  • 迭代器是一个可以标识序列中元素的对象
  • 迭代器的使用令算法不依赖于容器类型
  • 迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似,事实上,指向数组中某一元素的指针就是一个迭代器
  • 但许多迭代器不仅仅是指针,比如可定义一个边界检查迭代器,当试图使它指向[begin:end)之外的内容时就会抛出异常
  • 通过迭代器可以读取它指向的元素,*迭代器名就表示迭代器指向的元素。通过非常量迭代器还能修改其指向的元素
  • 序列是STL中的核心概念,数据集合是一个序列,序列具有头部和尾部
  • 可利用迭代器实现算法与数据的连接
  • 程序员了解迭代器的使用方法,数据提供者向程序员提供相应迭代器而不是数据存储的细节
  • STL算法和容器可以共同完成很强大的功能,是因为它们根本不知道对方的存在
  • STL包含大概10中容器和60种由迭代器相连接的算法

泛型

  • 模板所支持的类型是宽泛的,没有限制的,我们可以使用任意类型来替换,这种编程方式称为泛型编程(Generic Programming)
  • 推出泛型最直接的动力来源于对通用算法(查找、排序、删除)的封装
  • 泛型算法本身不会执行容器的操作,它们只会运行于迭代器之上,执行迭代器的操作
  • 算法永远不会改变容器的大小,算法可能改变容器中保存元素的值,也可能在容器中移动元素,但永远不会直接添加或删除元素
  • 标准库算法都对一个范围内的元素进行操作,此范围称作“输入范围”,算法用前两个参数表示此范围,两个参数分别指向要处理的第一个元素和尾元素之后位置的迭代器
  • 理解算法最基本的方法就是了解它们是否读取元素、改变元素或重排元素顺序
  • 任何算法的基本特征是它要求迭代器提供哪些操作
  • 标准库定义了约100个类型无关的对序列进行操作的算法

[c++] 模板、迭代器、泛型的更多相关文章

  1. -1-3 java集合框架基础 java集合体系结构 Collection 常用java集合框架 如何选择集合 迭代器 泛型 通配符概念 Properties 集合 迭代器

    集合又称之为容器存储对象的一种方式 •数组虽然也可以存储对象,但长度是固定的:显然需要可变长度的容器 集合和数组的区别?                 A:长度区别                  ...

  2. C/C++程序基础 (十)模板和泛型

    什么是泛型编程 基于模板,有效将算法和数据结构分离. 模板 包括类型和参数 模板函数:抽象的函数定义,代表一类同构函数.编译器在其调用位置自动完成对应模板函数的实例化. 模板类:抽象的类定义,代表更高 ...

  3. 【C++ 模板迭代器实例/半素数】

    题目:判断一个数是不是两个素数的乘积,是输出YES,不是输出NO.数据范围为2-1000000. 为了解决这个问题,我们继续使用STL——vector & set,分别用来存储素数和半素数.为 ...

  4. 第十章 泛型程序设计与C++标准模板库 泛型程序设计及STL的结构

  5. 用lambda表达式和std::function类模板改进泛型抽象工厂设计

  6. 8、泛型程序设计与c++标准模板库1、泛型程序设计的概念和术语

    有效地利用已有的成果,将经典的.优秀的算法标准化.模块化,从而提高软件的生产率,是软件产业化的需求,为了实现这一需求,不仅需要面向对象设计思想,而且需要泛型程序设计思想. c++语言提供的标准模板库( ...

  7. C++ 泛型程序设计与STL模板库(1)---泛型程序设计简介及STL简介与结构

    泛型程序设计的基本概念 编写不依赖于具体数据类型的程序 将算法从特定的数据结构中抽象出来,成为通用的 C++的模板为泛型程序设计奠定了关键的基础 术语:概念 用来界定具备一定功能的数据类型.例如: 将 ...

  8. 聊聊 C# 和 C++ 中的 泛型模板 底层玩法

    最近在看 C++ 的方法和类模板,我就在想 C# 中也是有这个概念的,不过叫法不一样,人家叫模板,我们叫泛型,哈哈,有点意思,这一篇我们来聊聊它们底层是怎么玩的? 一:C++ 中的模板玩法 毕竟 C+ ...

  9. 标准模板库--STL

    标准模板库STL 1.泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用 C++中有两个方面体现重用: 1.面向对象的思想:继承和多态,标准类库 2.泛型程序设计(generic progra ...

  10. lua 10 迭代器

    转自:http://www.runoob.com/lua/lua-iterators.html 迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表 ...

随机推荐

  1. epoll poll select区别

    函数依赖 ( Functional Dependency,FD) select:http://www.cnblogs.com/Anker/archive/2013/08/14/3258674.html ...

  2. JMeter元件作用域实践指南

    从一个问题说起 对于以下测试脚本: 为了能调用进入房间接口,需要从考场接口获取考场token.为了调用考场接口,需要从登陆接口获取登陆token.元件说明如下: 学生登录,提取登录${token}传入 ...

  3. [Fundamental of Power Electronics]-PART II-9. 控制器设计-9.4 稳定性

    9.4 稳定性 众所周知的是,增加反馈回路可能会导致原本稳定的系统变得不稳定.尽管原变换器传递函数(式(9.1))以及环路增益\(T(s)\)不包含右半平面极点,但式(9.4)的闭环传递函数仍然可能存 ...

  4. 梳理一下最近准备蓝桥杯时学习DP问题的想法

    学习时间不长,记录的只是学习过程的思路和想法,不能保证正确,代码可以在acwing上AC. 01背包问题: 1.首先是简单的01背包问题 2.先确定状态,f[i][j]表示有第i件物品,时间为j的最大 ...

  5. 02-MySQL主要配置文件

    一.二进制日志log-bin 作用:主从复制 二.错误日志 log-err 默认关闭,记录严重的警告和错误信息,每次启动和关闭的详细信息 三.慢查询日志log 默认关闭,记录查询的sql语句,如果开启 ...

  6. 【软件推荐】使用Cmder替换Windows自带的控制台

    安装地址 进入cmder官网,下载相应版本. 如果本地已经安装了git,可以选择mini版本. 将 λ 替换为 $ 当前cmder默认的提示符是λ,看上去总是有点不习惯. 打开cmder目录下的ven ...

  7. 零基础学Java,PayPal技术专家手把手带你入门

    在最权威的 TIOBE 编程语言排名榜单上,Java 常年稳居第一,可以说是世界上应用最为广泛的一门语言. 同时,在微服务.云计算.大数据.Android App 开发等领域,Java 也是当之无愧的 ...

  8. Jmeter对数据库批量增删改查

    本文主要的内容是使用Jmeter对数据库进行数据的操作,包括单条语句的增删改查,多条语句的增删改查,本文主要介绍操作流程,关于流程的运作原理,对原理感兴趣的同学可自行查阅资料. 首先需要准备一个数据库 ...

  9. Day06_30_抽象类(Abstract)

    抽象类 Abstract 什么是抽象类? 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就 ...

  10. python进阶(17)协程

    协程 协程(Coroutine),又称微线程,纤程.(协程是一种用户态的轻量级线程)   作用:在执行 A 函数的时候,可以随时中断,去执行 B 函数,然后中断B函数,继续执行 A 函数 (可以自动切 ...