——整理自《Effective STL》
一、确保容器中的拷贝操作是轻量级的。
理由:对于序列容器vector、deque和string等的插入或删除(中间元素),会造成元素的移动(拷贝);排序算法、next_permutation、previous_permutation、remove、unique、reverse等都会造成元素的拷贝。
因此,如果容器中元素太过复杂,如自定义的类型在拷贝的时候,拷贝会造成性能瓶颈。同时,如果以基类作构造一个容易的时候,当你插入派生类的时候会默认强制转换为基类类型,因此派生出来的部分就丢失了。
.
解决:使用对象的指针容器是一个很好的解决方案。
如:vector<Widget *>pvw;
二、用empty()代替size()检查容器是否为0
理由:对于所有的标准容器,empty是一个常数时间的操作,但对于一些list实现,size花费线性时间。
三、拷贝vector v2后半部分的元素到vector v1中去:
1)v1.assign(v2.begin() + v2.size() / 2, v2.end());//两个迭代器指针指向拷贝的首尾地址。
assign是一个很优秀的序列容器的成员函数。注意仅在vector、string、deque和list有效。
2)v1.insert(v1.end(), v2.begin() + v2.size() / 2, v2.end());
3)copy(v2.begin() + v2.size() / 2, v2.end(), back_inserter(v1));
4) vector<Widget> v1, v2; // 假设v1和v2是Widget的vector
v1.clear();
for (vector<Widget>::const_iterator ci = v2.begin() + v2.size() / 2;
ci != v2.end();
++ci)
v1.push_back(*ci);
性能依次降低!且手写for循环代码不简洁,易出错。
四、当使用new得指针的容器时,记得在销毁容器前delete那些指针
理由:指针容器在作用域结束的时候只会释放容器中的指针,不会释放指针指向的堆空间。
五、删除容器中元素的技巧
1)连续内存容器(vector 、deque或string)方法:eraser-remove法
如有容器Container<int> C;
删除容器中值为1963的所有对象:C.erase(remove(C.begin(),C.end(),1963),C.end());
该方法同样适用于list,具体步骤都是首先从后往前依次覆盖掉值为1963的节点,然后调用erase擦出移动后尾巴上多余的节点(实际上并没有清空这块内存,而是讲end指针前移)。但是考虑到list特殊的数据结构,因此使用list的成员函数remove更有效。
2)关联容器(set、multiset、map或multimap)
不是线性的,最好不使用remove方法,可能会覆盖容器值,因此删除最好使用erase,对数时间
c.erase(1963);//当c是标注关联容器时,这是最佳方法。
未完待续.....