1、c++ STL中提供了顺序容器和关联容器。vector,list,deque为顺序容器;map,set,multiset,multimap为关联容器。其中每种容器均提供默认的构造函数来初始化容器对象。
vector<string>str(5);
在这句代码中,首先容器使用string的默认构造函数创建了一个临时值来创建容器对象,并且调用拷贝构造函数,将这个临时值分别赋值给其他对象。
2、容器初始化时要注意,有些方式只适用于顺序容器:
C c(n,t);
C c(n);
在上述代码中,n代表整数时,表示创建n个对象,这种情况下接受容器大小做形参的构造函数只适用于顺序容器,而不适用于关联容器。
3、在将一个容器复制给另一个容器时,一定要注意,容器的类型及元素类型均要相同才可;否则不能复制;
vector<int>a;
list<int>b(a);
上述代码因为容器类型不同,所以是错误的。
4、为了解决不同容器之间可以相互复制的问题,我们可以传递一对迭代器,将两个迭代器之间的元素进行复制。这样也就意味着,我们不仅可以复制无法直接复制的容器的值,还可以复制其他容器的子序列。
5、任意容器当中的元素应该满足以下两个条件:
(1)、元素的类型必须支持赋值运算;
(2)、元素的类型必须支持复制运算;
其实说的更直白一点,要有拷贝构造函数,要重载赋值运算符;因此,引用,IO,还有auto_ptr是不能做容器元素的。
6、考虑以下几行代码:
vector<Foo>a;
vector<Foo>b(10);
vector<Foo>c(10,5);
在第一行中,实际上不会调用Foo类的默认构造函数;第二行代码中会先调用默认构造函数,再调用拷贝构造函数;第三行代码中会先调用含有一个int型参数的构造函数,再调用拷贝构造函数。
7、容器的容器中,需要注意一点;就是格式:
vector< vector<int> >a;
vector< vector<int>>b;
第一行是对的,第二行是错的,看出来了吧,就是要空格。
8、说起迭代器,最容易让人想到的就是运算。但是只有vector和deque支持元素的快速随机访问,因此只有vector和deque支持关系运算符,<,>,=。
9、在迭代器所指向的范围中,前闭后开,[first,last);除此之外,迭代器只能指向容器的第一个位置到最后一个位置的下一个位置;并且容器的last迭代器是不允许超过first迭代器的。
10、由于编译器无法知道,迭代器关联的是哪个容器,因此,在做一些改变容器的元素的操作或是迭代器的操作时,可能导致迭代器失效。
11、在容器中添加元素时,增加的都是元素的副本。
12、在使用insert时,一定要注意,是在其指向位置的前面插入元素,而非之后。
13、任何insert和push操作都会是vector和deque容器的迭代器失效,所以在循环中要确保每一次循环迭代器是有效的。
vector<int>::iterator first = v.begin(),last = v.end();
while(first!=last)
{
first = v.insert(first,42);
}
在上述代码中,last经过第一次插入后就已经失效了,不再指向v,也不指向新的容器。所以一定要注意迭代器失效的情况,否则程序当中很难查找错误。
14、容器均可只能关系运算符的比较。
15、容器通过resize()来改变容器的长度大小;如果当前长度大于新的长度值,这该容器后部的元素会被删除;如果当前长度小于新的长度值,则使用默认值来初始化多余的元素。
resize操作可能因此vector和deque的迭代器失效。如果resize进行压缩操作,则指向已删除的元素的迭代器失效。
16、c.at(n)这种操作只适用于vector和deque容器。
17、容器的赋值操作是需要非常注意的。c1=c2;当这种赋值情况发生时,首先将c1中的所有元素全部删除,再将c2中的元素复制到c1中;此时的c1与c2必须容器类型和元素类型均相同;c.assgin(b,e);此时b,e为迭代器,并且必须不是指向c中元素的迭代器。这时首先删除c中元素,然后将迭代器b,e所指范围内的元素复制到c中。
18、相比赋值和assign函数,swap函数运行效率要高很多。swap交换两个容器的值,既不会删除或插入元素,而且保证在常量时间内交换。由于容器内没有移动元素,因此迭代器依然有效。即:之前指向哪个元素的迭代器,依然指向哪个迭代器。
19、capacity()是指容器在必须分配新存储空间之前,可以存储的元素的总数;而size是指容器中当前拥有的元素个数。reserve是分配内存空间。