模板的基本概念
模板是C++发展历程中浓墨重彩的一笔,它是C++区别于其他变成语言的核心支柱之一,它使得成为C++被世界各地的程序员认可的优秀编程语言。STL是C++中的标准模板库,其核心六大组件分别为:容器、迭代器、算法、仿函数、适配器、空间配置器。今天我只讲解一下迭代器相关的概念及其用法。
迭代器(iterator)
迭代器是一种近似于指针的组件,不同的平台和不同的模板之间可能会有差别,但都可以近似看作指针。迭代器实际上是C++封装特性的一种体现形式,因为迭代器屏蔽了底层实现细节,无论原本是什么数据结构,它都提供了一种统一类似访问容器的方式,不需要关心底层结构和实现细节。所以说迭代器是一种非常方便的工具,在后面的string类的学习中我们也会使用到它。
begin是返回开始位置的迭代器,end是最后一个有效字符的下一个位置的迭代器,也就是‘\0’的位置,同理也有反向迭代器,可以反向遍历,对应rbegin和rend。
说到迭代器就不得不说到string类和STL中一个非常方便的遍历语法’范围for‘,大致语法如下,其中s代表的是原对象,ch代表的是暂存字符的对象,范围for是一个非常方便的语法,它可以自动赋值,自动迭代,自动判断结束,它的底层也是迭代器。auto这个关键字在C++中代表自动推导,它可以自动推导变量的类型。主要应用场景是用于替换过长的类型名以及范围for中使用,可代价是牺牲了代码的可读性,需要谨慎使用
for(auto ch : s)
{
...
}
string类
string类是用于管理字符串的类,它可以直接用string(...)的形式进行初始化,也可以直接用cout << ... 的形式,因为string重载了流插入和流提取。
string类的常见接口
1、size/length:获取字符串长度,两者几乎没有区别,只是size更加规范化,length是早期遗留的接口,因为length不好表示除链式结构外的其他数据结构,所以一般统一用size来表示更加规范。
2、capacity:获取容量,关于初始容量和扩容规格,不同的编译器会进行不同的处理,在VS里,string类的初始容量有两个,分别是16和32,主要看初始化时的字符串大小,除此之外,超出32的初始化或插入编译器会按每次1.5倍的倍数扩容。
3、reserve:将容量调整到某个值,写法是reserve(size_t n),不过如果要调整的容量小于原本容器中所存的字符串的长度,编译器一般不会进行缩容,要缩最多也就缩到size的大小。
4、clear:清理容器中的数据但不清理容量。
5、push_back、append、+=:三个接口都是尾插,不同的是push_back是尾插一个字符,append是尾插一个字符串,+=是最方便的尾插字符的方式,它可以尾插任意数量的字符,虽然底层实现仍然是push_back和append,但是在实际写代码中+=是写起来最方便,可读性也最高的写法,故一般推荐用+=。
6、insert/erase:insert是在某位置之前插入字符串,erase是从n位置开始删除m个字符,具体写法是insert(size_t pos, size_t n, char* ch),erase(size_t pos, size_t n = npos),其中这个默认的缺省值npos我们下面再讲,但是这两个接口建议谨慎使用,因为它们都要挪动字符,不可避免的会产生效率问题。
7、npos:npos并不是一个接口,而是string里定义的一个静态常量,它的值是npos = -1,即表示整型的最大值,作为缺省值出现时,它一般是告诉编译器,如果没有给参数,就判定为size,即字符串的最大值,如果给的参数大于size,也是判定为size,不会越界。
8、replace:用于替换字符,既可以将少的替换成多的,也可以把多的替换成少的,编译器会自动调整字符位置和容量大小,但是同样谨慎使用,因为也需要挪动字符。
9、operate[ ]:string还重载了方括号,这意味着它可以将string类的对象像数组一样使用,只要给出下标就可以对字符进行修改。
10、find系列:find,从pos位置起查找某个字符或字符串,默认从头开始;rfind倒着查找,find_first_of,将原字符串中的所有字符都与给出的某些字符进行别对,只要于给出的字符中任意一个匹配就返回下标;find_last_of,与上述同理,倒着查找;find_first_not_of,与上述同理,不过是返回不匹配字符位置的下标;find_last_not_of,与上述同理,倒着查找。
11、substr:将字符串从pos开始的len个字符构建为一个字串进行返回,如果没给len则缺省值为npos。
12、getline:在命令行输入中遇到换行符才终止,因为C++的io流默认遇到空格或换行符就停止读取,所以如果想要输入带空格的字符串时需要使用getline才能正常输入,除此之外getline也支持自己定义终止符,只有读取到终止符时才停止。
string类由于其在STL出现之前就已经被编写出来了,导致其在设计上其实有很多的冗余,很多接口过于复杂,实际也不常用, 所以我们只需要认识其中的常用接口就行了
总结
模板赋予了 C++ 无与伦比的表达力与泛型能力,让"一次编写,多处复用"从口号变为现实。正是在模板的土壤之上,STL六大组件才得以生长——迭代器屏蔽底层差异,提供统一的遍历方式;string 虽是模板的"前辈",在 STL 之前就已问世,却同样受益于模板思想,用一套丰富的接口为字符串管理提供了完整方案。理解模板不仅仅是在学一个语法特性,更是在理解 C++对于抽象、复用与效率的底层哲学。掌握迭代器的统一访问思维,熟练运用 string常用接口,同时保持对性能敏感操作的警觉——这三者合在一起,是每一个 C++ 初学者走向进阶的必经之路。
3014



被折叠的 条评论
为什么被折叠?



