一、类模板简介:
在现今的C++标准模板库中,几乎所有的东西都被设计为template形式,不支持模板,就无法使用标准程序库。模板库可以认为是针对一个或多个尚未明确的类型而编写一套函数或类型。模板是C++的一个新特性。通过使用模板,C++允许推迟对某些类型的选择,直到想使用模板或者对模板进行专门化处理时,使用模板,可以让程序员面对相似而又略有不同特性时,更快捷地编写代码,提高开发效率。
C++模板功能思想:
泛型编程完美思路:
设想能否研制一种编程机制,让一个函数适应所有的数据类型,包括自己定义的。实现这种机制,既然适应所有的数据类型,称为泛型编程(Generic Programming)。
泛型编程最初提出时的动机很简单直接,就是发明一种语言机制,能够实现:
- 一个通用的标准容器库。所谓通用的标准容器库,就是要能够做到,如一个list类存放所有可能类型的对象;
- 泛型编程让编写完全一般化并可以重复使用的算法,其效率与针对某特定数据类型而设计的算法相同。泛型即是指具有在多种数据类型上皆可操作的含义,这样算法与数据结构完全分离。其中算法是泛型的,不与任何特定数据结构或对象类型联系在一起。
泛型编程的代表作品STL是一种高效、泛型、可交互操作的软件组件。STL以迭代器(iterators)和容器(containers)为基础,是一种泛型算法(generic algoritms)库,容器的存在这些算法又东西可操作。STL包含各种泛型算法(algoritms) 、泛型迭代(iterator)、泛型容器(containers)以及函数对象(function objects)。STL并非只是一些有用组件的集合,它是描述软件组件抽象需求条件的一个正规而有条理的架构。
泛型的第一好处是编译时的严格类型检查。这是集合框架最重要的一个特点。此为,泛型消除了绝大多数的类型转换。如没有泛型,当使用集合框架时,不得不进行类型转换。
以上概括为:它是把数据类型(包括自己定义的class类型)作为一种参数传递进来的机制。
C++模板:
让程序更加智能,C++很需要泛型这种新的编程模式,于是引用了模板这个功能。也就是说在C++中,引入了关键template。
使用模板是为了实现泛型,可以减轻编程的工作量,增加函数的重用性。注意重用性几乎是编程的基本思路,不然也不会发明函数这种功能了。
C++STL的渊源:
有了泛型编程思想,有了模板功能,C++程序员就可以编写出很多通用的针对不同数据类型的算法,其中,STL脱颖而出,称为C++标准,只需掌握这个标准,就不用自己费心费力从头编写一些算法。这就是所谓的开发基本思想:不要重复发明轮子。
简单的说,STL(Standard Template Libarary)标准模板库,是一个具有高可用性的、高效的C++程序库。该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法,为广大C++程序员提供了一个可扩展的应用框架,高度体现了软件的可复用性。刚开始可以理解为C++内置的函数库、类算法框架库等。
C++基本概念通览:
- 命名空间:name space是指标识符的可见范围或者有效范围。定义命名空间的目的是防止出现名称冲突现象。命名空间是C++中一项较新的特性。为了将多个程序员开发(或厂商)开发的代码便捷、高效地组合起来,防止重复的函数名、类名等,命名空间可将不同的代码封装在有效的范围内;
- 头文件:头文件的功能主要是将原程序片段收集到一起,形成一个提供给编译程序的文件,一般情况下,头文件中只包含各种声明、常量定义、预编译、注释、类型定义、模板定义等。常规的函数定义、数据定义、导出的模板定义等不应该出现在头文件中。
- 面向对象的程序设计:面向对象时C/C++语言解决问题的一种方法。原来的程序开发是面向过程的。面向过程的程序设计主要考虑解决问题的先后顺序、措施安排等,具有典型的过程性。而面向对象的程序设计主要是建立在各种对象基础的软件开发,每一个具有独立特性和相应功能的个体均可以作为一个对象加以处理。
- C++中的声明和定义:在程序开发领域,声明是指当一个计算机程序需要调用内存空间时,对内存发出的“占位”指令;定义是指声明的变量、函数、类等呈现或描述出来,为其提供一个意义相当的表达,并表明其与众不同之处,最终目的是显示其内涵。
- 指针:指针是C语言中一个重要概念,也是C语言的重要特色。C++沿袭了C语言的这一特色。正确而灵活地使用指针,可以有效地表示复杂的数据结构、动态分配内存、便捷地使用字符串、方便地使用数组、直接处理内存、函数可以返回多个数值等;在内存中,变量存储在特定的地址,通过地址可以找到所需的变量,变量在内存中的地址“指向”该变量单元。一个变量的地址称为该变量的“指针”。如有一个变量用来存储另一个变量的地址,则称它为“指针变量”;在学习过程中,要注意区分指针和指针变量。指针指的是该变量在内存中的存储地址;而指针变量指的是该变量的值是一个指向其他变量的指针值。
- 函数:C/C++程序至少需要一个main()函数。程序往往由多个函数组成。函数是C++源程序的基本模块,通过调用相应的函数,可以实现特定的功能。C/C++语言提供了强大的、极为丰富的库函数。另外,用户或程序开发者可以把自己的思想或算法编写成一个相对独立的函数模块。
- 函数中变量:局部变量和全局变量;变量的存储类别,在使用函数时涉及不同的存储方分为静态存储方式和动态存储方式;全局变量使用静态存储方式;函数的形参和普通局部变量使用动态存储方式:
- auto类型是默认类型,可以省略不写;
- static类型属于静态存储类型,当希望函数中的局部变量的值在函数调用结束后不消失而保留原值时,可用关键字static声明该局部变量;
- C语言中将局部变量的值放在CPU中的寄存器中,这种变量称为“寄存器变量”,用关键字register作声明;
- 如外部变量不存在文件的开头定义,其有效的作用范围只限于定义到文件末尾。函数需要引用该外部变量,则应该在引用之前用关键字extern对该变量作“外部声明”,表示该变量是一个已经定义外部变量。有了次“声明”起,合法地使用该外部变量。
- 文件:C/C++中的文件一般是指,存储在外部介质上数据的集合,并且是一组相关数据的有序集合。当文件被使用时,将其调入内存中。文件可分为两种:一种是驻留在磁盘或其他外部介质的一个有序数据集,可以是数据文件、可执行程序;另一种是设备文件,是指和主机相联的各种设备,像显示器、键盘、打印机等;外部设备一般可以看作一个文件来进行管理,它们的输入、输出等同于对磁盘文件的读和写。
- 程序的编译和链接:
- 程序编译:是指将编辑好的源文件翻译成二进制目标代码的过程,编译过程时使用C语言提供的编译程序完成的,不同操作系统下的各种编译器的使用命令不完全相同,使用时应注意计算机环境。编译时,编译器首先要对源程序中的每一个语句检查语法错误。当发现错误后,会提示错误的位置和错误类型的信息。要再次调用编辑器进行查错修改,之后再编译,直到排除所有语法和语义错误。正确的源程序文件经过编译后在磁盘上生成目标文件
- 程序的链接:编译后产生的目标文件是可重定位的程序模块,不能直接运行。链接程序是把目标文件和其他分别进行编译生成的目标程序木块及系统提供的标准库函数链接在一起,生成可运行的可执行文件的过程。
- 程序的启动和终止:对于任何一个C/C++程序,程序执行时总是从main()函数开始,之后一次或者顺序执行main()函数中的程序代码,实现其中其他函数的各种功能。
- 异常处理:异常处理机制可看作是编译时的类型检查和歧义性控制机制在运行中的对应物。
类模板定义:
- 模板库(STL):STL另一个重要特性是它不是面向对象的。STL主要依赖于模板。这使得STL的组件具有广泛通用性和底层特性。由于STL是基于模板的,内联函数的使用使得生成的代码短小高效。
- 类模版实例化:类模版仅仅是模板,如何使用模板就涉及类模板的实例化问题。模板实例化一般指使用模板类和模板参数生成一个类声明的过程。
- 类模板的成员函数:可被类模板实例化产生的类所拥有。每个类模板都拥有自己相应的成员函数,这些函数可被模板的实例调用。
- 类模板的静态数据成员:被static修饰,意味着它为该类的所有实例所共享,即当某个类的实力修改了改静态成员变量,其修改值为该类的其他所有实例所见。
成员模板:
一个模板可以在一个类或类模版中声明,这样的类模版称为成员模版;成员模版的定义既可以在类(或类模版)定义内部,也可以在类(类模版)定义的外部;当类模版的成员模板在类模版定义的外部定义时,应该完整地指出类模版的参数和成员模版的参数。
友元模版:
- 非模版函数、类作为实例的友元;
- 模版函数、模版类作为同类型实例类的友元;
- 模版函数、类作为不同类型实例类的友元。
函数模版:
函数模版定义一个无限的相关函数集合。当函数除了数据类型不一致外,其余的处理全部相同,此时函数模版随之诞生,这也是创建函数模版的原因;
函数模版可以定义参数化的非成员函数,能够不同类型的参数调用相同的函数,由编译器决定该采用哪种类型,从模板函数中生成相应的代码。
类模版的参数:
模版的参数可以是类型参数,也可以由常规类型的参数。并且一个模板可有多个参数。
模板库简介:
STL的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),几乎所有的代码都采用模板类和模板函数的方式,在C++标准中,STL被组织为13个头文件:<algorithm>、<deque>、<functional>、<iterator>、<verctor>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack>和<utility>。
STL的组件:
STL是C++标准程序库的核心。STL内所有组件都由模板构成,其元素可以是任意型别。程序通过选用恰当的群集类别,调用其成员函数和算法数据,就万事大吉了,代价是STL并不好理解。
- 容器:用来管理某类对象的集合;
- 迭代器:用来在一个对象群集的元素上进行遍历动作。对象集可能是容器,也可能是容器的一部分。迭代器的主要用途是为容器提供了一组很小的公共接口,利用这个接口,某项操作可以行进至群集内的下一个元素。每种容器都提供了各自的迭代器,迭代器了解该容器的内部结构,所以能够正确行进。迭代器的接口和一般指针差不多;
- 算法:用来处理群集内的元素。可以出于不同目的的搜寻、排序、修改、使用那些元素。所有容器的迭代器都提供一致的接口,通过迭代器的协助,算法程序可以用于容器。
- 仿函数:可以理解为函数的一般形式。仿函数有几种不同的约束,对于编程来说,仿函数非常重要。
- 内存配置器:配接器可以实现不同类之间的数据转换。
二、C++中的字符串:
C++标准程序库中的字符串处理类string,在最初的C语言中,头文件string.h提供了一系列字符串函数,早期的C++为处理字符串提供了各自的类,string类由头文件<string>支持,该类包含了大量方法,并且包括了若干构造函数,用于字符串赋给变量、合并字符串、比较字符串和访问各个元素的重载操作符、查找字符和子字符串的方法等。
在STL中还提供了另一个模版类:auto_ptr类。主要用于管理动态内存分配。如使用new函数分配堆中的内存,而又不记得回收这部分内存,在会导致内存泄漏。必须使用delete语句释放该内存块。即使在函数末端添加了delete语句释放内存,还需要再任何跳出该函数的雨具(如抛出异常)之前添加释放内存的处理,例如,goto语句,throw