标准STL序列容器:vector、string、deque、list
标准STL关联容器:set、multiset、map、multimap
序列容器支持push_front或push_back操作,关联容器则支持对数时间复杂度的lower_bound、upper_bound和equal_range成员函数操作。
当向容器中利用insert或push_back添加一个对象的时候,进入容器的是指定的对象的拷贝,而不对原对象本身。
拷进去,拷出来,是STL的工作方式。
用empty来代替检查size()是否为0
对于任何容器c,写下if(c.size()==0)...等价于if(c.empty())...,且首选empty()。因对于所有的标准容器,empty是一个常数时间的操作,但对于一些list实现,size花费线性时间。
尽量使用区间成员函数代替它们的单元素兄弟
如:给定两个vector,v1和v2,使v1的内容和v2的后半部分一样的最简单方式是:
v1.assign(v2.begin()+v2.size()/2, v2.end());
assign对于所有的标准序列容器(vector, string, deque, list)都有效。
函数原型:void container::assign(InputIterator begin,InputIterater end);
尽量用vector和string来代替动态分配的数组
无论何时,当发现准备动态分配一个数组时(试图写“new T[...]”),应该首先考虑使用一个vector或一个string(一般来说,当T是一个字符类型时使用string,否则使用vector,当然 用vector<char>可能会是一个更好的选择)。当元素添加到这些容器中时它们的内存会增长,而当一个vector或string销毁 时,它的析构函数会自动销毁容器中的元素,回收存放那些元素的内存。
vector和string提供的四个成员函数:
size() 告诉容器中有多少元素。
capacity() 告诉容器在它已经分配的内存中可以容纳多少元素。若想知道一个vector或string中有多少没有被占用的内存,必须是:capacity()-size()
resize(Container::size_type n) 强制把容器改为容纳n个元素。调用resize后,size将会返回n。如果n小于当前大小,容器尾部的元素会被销毁。如果n大于当前大小,新默认构造元 素会添加到容器尾部。如果n大于当前容量,在元素加入之前会发生重新分配。
reserve(Container::size_type n)强制容器把它的容量改为至少n,避免重新分配的关键是使用reserve尽快把容器的容量设置为足够大,最好在容器被构造之后立刻进行。
如:假定要建立一个容纳1-1000值的vector<int>。没有使用reserve,做法为:
vector<int> v;
for(int i=1; i<=1000; ++i) v.push_back(i);
在大多数的STL实现中,这段代码在循环过程中将会导致2至10次重表分配。(vector在重表分配发生时一般把容量翻倍,1000约等于2^10)
使用reserve,代码可改为:
vector<int> v;
v.reserve(1000);
for(int i=1;i<=1000;++i) v.push_back(i);
这在循环中不会发生重新分配。且调用reserve不改变容器中对象的个数。
通常使用reserve避免重新分配的两种情况:
1)当确切或大约知道多少元素将最后出现在容器中
2)保留可能需要的最大的空间
将vector和string的数据传给遗留的API
最常见的一个是已经存在的遗留的C风格API接受的是数组和char*指针,而不是vector和string对象。
若是一个vector对象v,因需要得到一个指向v中数据的指针,以使得它可以被当作一个数组,只要使用&v[0]即可。对于string对象s,转化成字符数组只需用s.c_str()即可。
为了防止v是空的,导致产生一个指向不存在的东西的指针,写法通常为:
if(!v.empty())
{
doSomething(&v[0],v.size());
}
Effective STL 学习(1)
最新推荐文章于 2024-04-02 18:01:59 发布