声明:本读书笔记仅表达对书的理解,如有任何错误欢迎指出
前言:文章的前几章是介绍标准库抽象的程序,从这章开始,作者开始介绍自己定义的抽象(说白了就是自己定义一些函数、数据类型等等)
一、泛型函数:定义时不明确参数类型,使用时进行赋予,可以根据输入变化
(1) 泛型函数是通过模版函数实现的(猜测),它定义了具有相似特征的一类函数,这些函数可能具有不同类型的参数,因此在定义时不表明参数类型,只有实例化后才有明确的类型,这种参数叫模版参数。
(2) 函数的行为受两个部分限制,内部是参数的使用方式约束、外部是标准库的约束)
(3)泛型函数定义
template <class T>
T 函数名(T v) ps:T即为参数和返回值的类型,两者也可以不同
(4) 使用模版参数的size_type 时需要加上typename
例如:typedef typename vector<int>::size_type vcz;
(5) string 没有除法运算
(6) 为了模版实例化,必须满足:1 系统要求可以访问模版的定义(头和源文件)2实例化是在链接时实现而非编译;
(7)注意泛型函数的参数赋值后,容易出现参数不匹配的问题;
(8)find的使用方式 find(c.begin(),c.end(),val) c.find(val) find(c,val)
(9) 向量的迭代器支持r.begin()+5,但是链表的迭代器不支持,
(10)向量、链表、string均属于顺序容器,而map是关联容器,存储的方式不同
向量、string与链表的访问方式不同,前者可以随机,后者只能顺序
(11)只有向量和string支持sort算法
(12)reverse函数是翻转元素顺序, swap函数是交换参数的值;
(13)it++即先把it给后面的操作,再加1,++在前面还是后面在迭代的算法里面非常常见;
(14)库定义了五种迭代器,不同类型迭代器可以明确不同容器所支持的算法,迭代器的种类和容器的访问策略对应
容器---访问策略---迭代器---算法
策略有:
<1>顺序只读访问--输入迭代器
输入迭代器:支持++、==、!=、it->end的迭代器
库函数举例:find
<2>顺序只写访问--输出迭代器
输出迭代器:允许赋值操作,在两次赋值操作之间必须且只能有一次++操作,例如back_inserter
库函数举例:copy
<3>顺序读写访问--正向迭代器
正向迭代器:*it(读写)、++但是--不行,赋值,it->end
库函数举例:replace
ps:顺序的意思是一旦处理了就不再访问该元素
<4>可逆访问--双向迭代器
双向迭代器:支持正向迭代器的操作以及--,标准库所有的容器都支持双向迭代器
库函数举例:reverse
<5>随机访问--随机访问迭代器
随机访问迭代器:满足双向迭代器的要求,以及对迭代器p+n,p-q,p[n](等价于*(p+n)),p>q;
库函数举例:binary_search、sort
向量和string都是随机访问迭代器,但是链表是双向迭代器
(15)算法需要两个参数来制定区间
(16)指定区间的第二个参数是最后一个参数的下一位,这样以方丢失信息,例如end()指向最后的下一位
(17)每一种容器都要为了他的迭代器而支持一个越界值
(18)并不是所有迭代器都与容器相关联,back_inerter(c)不满足任何其他迭代器要求,它属于库定义的为了链接输入和输出流的迭代器。
(19)istream的迭代器满足输入迭代器的要求,ostream的迭代器满足输出迭代器的要求。
(20)输入流迭代器istream_iterator,它有一个缺省值,当到达结尾或者报错就会与缺省等价。
istream_iterator<int>(cin);
ostream_iterator<int>(cout," ")后面的空格是为了分隔的
(21) c++的输入和输出都是带类型的,通常隐藏在读入中;
(22)迭代器是算法和容器之间的一个粘合剂;
(23) 在函数调用过程中凡事使用const 必须全程标明,否则会报错;
(24) #pragma once是c++杂注,在头文件开头表明这个,可以保证头文件只编译一次,
#pragma once与#ifndef的区别:
#ifndef是防止宏名字重复,同一文件不会被包含多次,且内容相同的两个文件也不会被重复包含,但是宏名相同的两个头会撞车;
#pragma once是指同一个文件不会包含多次,但是同一个文件中有两个相同的宏就无法保证;
(25)hpp文件就是cpp和h文件的合成体;
(26)函数源文件中表示对一个迭代器的谓词处理:p(*it);
(27) 模版函数不能分开定义,只能全部放在h(hpp)文件中;
(28)typename
vector<type>::iterator a
typedef typename std::vector<T>::size_type vec_sz;
(29) swap函数是为了交换,在algorithm头里面,迭代器内元素交换必须用这个;
(30) list是不支持随机访问的,因此他的迭代器不支持+/+=,但是vector 支持。
(31)关联容器不能使用back_insterter和push_back;
(32)
forward_list不支持push_back和emplace_back,list支持,vector和string不支持push_front和emplace_front
(33)课后习题8-8:
binary search中计算mid=(beg+end)/2与mid=beg+(end-beg)/2的区别