顺序容器:vector,list, deque
1.顺序容器的初始化:
a. C<T> c; 创建一个名为c的空容器
b. C<T> c(c2); 创建容器c2的副本c,c和c2必须有相同的容器类型,并存放相同类型的元素
c. C<T> c(b, e); c 初始化为一段元素的副本,使用迭代器时不要求容器类型相同,容器内的元素类型也可以不相同,只要能将要复制的元素转换为所构建的新容器的元素类型即可。(注意允许通过内置数组中的一对指针初始化容器,因为指针其实就相当于是迭代器)
接受容器大小做形参的构造函数只适用于顺序容器,而关联容器不支持。
d. C<T> c(n, t); 用n个值为t的元素创建容器c,其中t必须是c的元素类型的值,或者可以转换为该类型的值。
e. C<T> c(n);创建有n个值初始化元素的容器c,想比上面而言区别是没有提供初始化式,标准库将为该容器实现值初始化,当然元素类型必须是内置类型或者提供了默认构造函数的类类型(使用合成的默认构造函数也可)。
2.容器内元素类型约束:元素类型必须支持赋值运算;元素类型的对象必须可以复制。引用不支持一般意义的赋值运算,所以没有元素类型是引用的容器。IO库类型不支持复制或赋值,因此也不能创建存储IO类型对象的容器。支持复制和赋值是容器元素类型的最低要求,比如,
Foo没有默认构造函数,但提供了需要一个int型形参的构造函数
vector<Foo> empty;
vector<Foo> bad(10);//error 没有默认构造函数(当定义了一个构造函数后,系统不再合成默认构造函数)
vector<Foo> ok(10,1);
3.容器的容器,可以定义元素是容器类型的容器。注意定义容器的容器时,必须如下使用空格
vector< vector<string> > lines;必须用空格隔开两个相邻的>符号,否则系统会认为是>>,为右移操作符,导致编译错误。
4.迭代器和迭代器的范围,只有vector和deque的迭代器支持算术运算(iter+n;iter1+=iter2等)以及使用除了==和!=()(== 和!=适用于所有容器)之外的关系操作符来比较两个迭代器(>,>=,<,<=),原因在于这两种容器都支持通过元素位置实现的随机访问(元素是连续存放的,与链式区别开来),所以其迭代器可以有效的实现算术和关系运算,list容器的迭代器即不支持算法运算,也不支持关系运算,只提供自增(自减)<list内存区域不连续(链表),此时的++运算符被重载过>,以及相等(不等)运算。
5.c.push_front(t),在容器c的前端添加值为t的元素,只适用于list和deque,vector不支持(同样也不支持pop_front()操作)。此外list不支持随机访问,即c[n],c.at[n]不适用。
6.所有的容器类型都支持关系运算(注意不是迭代器),但是前提条件是容器的类型相同,且元素类型也必须相同,此外如果容器的元素类型不支持某种关系操作符,则该容器也就不能做这种关系(比较)运算,例如容器元素类型为Sales_item类,而这个类没有定义诸如<等关系操作符,所以元素类型为Sales_item类的容器也就不能进行相应的关系运算。
7.容器的赋值与swap,
c1=c2 删除容器c1的所哟元素,然后将c2的元素复制给c1,c1和c2的容器类型和元素类型必须相同。
c1.swap(c2),调用完后,c1存放的是c2原来的元素而c2存放的是c1原来的元素,其中c1和c2的容器类型和元素类型必须相同。
c.assign(b,e)重新设置c的元素,将迭代器b和e标记的范围内所有元素复制到c中(b,e不能指向C,因为assign首先删除容器中的所有元素)(这种操作是对“=”的补充,不要求容器类型一定相同,只要元素类型兼容就好--->即可以转换)
c.assign(n,t) 将c重设为存储为n个值为t的元素
8,容器的选用:vector和deque容器的内存区域是连续的,所以可以实现对元素快速的随机访问,但付出的代价是在任意位置插入和删除元素比在尾部插入和删除元素的开销更大(因为在其他位置插入或删除元素都要求移动被插入或删除元素右边的所有元素,但是deque由于是双端队列,所以在容器首部也能高效的实现插入和删除)。list容器表示不连续的内存区域,允许前向或后向逐个遍历元素,在任何位置都能高效的插入或者删除某个元素,另外由于连续性所以不支持随机访问,访问某个元素需要遍历涉及到的其他元素,效率不高。如果在编程时无法确定应该采用某种容器,则写代码时尽量只使用vector和list都容器提供的操作,使用迭代器而不是下标,并且避免随机访问,这样在有必要时可以很方便地将vector容器修改为使用list容器。
9.容器适配器:适配器是标准库中通用的概念,包括容器适配器,迭代器适配器和函数适配器。适配器的本质是使一事物的行为类似于另一事物的行为的一种机制,例如stack(栈)适配器可以使任何一种顺序容器以栈的方式工作,
stack<int> intStack; intStack.push(num);默认情况下栈适配器建立deque容器上,因此采用deque提供的操作来实现栈的功能,比如这个push操作就是通过deque提供的push_back实现的。