1.容器

来源:互联网 发布:网络课视频快进 编辑:程序博客网 时间:2024/06/15 07:56

Effective STL—容器

Item01

慎重选择容器类型

基于节点的容器指针,引用变为无效的次数少,正在删除的元素指向除外,如list。

Item02

不要试图编写独立于容器类型的代码
  • 不同的容器特性不一样
  • 迭代器失效的规则也不一样

可以采用typedef vector< Widget > widgetContainer类型定义的方式,减少改动的代码。

Item03

确保容器中的对象拷贝正确而高效

将子类型对象存入基类型容器时,子类特有的部分将会消失。

Item04

调用empty而不是检查size()是否为0

empty对于所有的标准容器都是常数时间操作,而对一些list实现,size耗费线性时间。

Item05

区间成员函数优先于与之对应的单元素成员函数
  • 区间创建:T obj( beg , end )
  • 区间插入:obj.insert( pos , beg , end )
  • 区间删除:obj.erase( beg , end )
  • 区间赋值:obj.assign( beg , end )

优势:

  • 写起来容易
  • 更易理解,意图明确,便于扩展
  • 效率高

Item06

当心C++编译器最烦人的分析机制

Widget w();        //函数声明而非默认构造,c++11中可以通过Widget w{}默认构造

int f(double d);          //函数声明int f(double (d));        //围绕参数名的括号被忽略int f(double);            //形参名可以去除
int g(double(*pf)());          //函数声明int g(double pf());            //隐式指针int g(double ());              //省去参数名,独立的括号则表明参数列表

可以通过非临时对象的形式表示

Item07

如果容器中包含了通过new操作创建的指针,切记在容器对象析构前将指针delete掉

可用智能指针来处理,即使在异常情况下也不用害怕

Item08

切勿创建包含auto_ptr的容器对象

因为auto_ptr的复制意味着所有权的移交,所以当进行sort时会导致成员的失效。

Item09

慎重选择删除元素的方法

①删除特定值的所有对象

  • vector,string,deque     erase-remove习惯用法:v.erase(remove(v.begin(),v.end(),5),v.end());
  • list               list::remove
  • 标准关联容器          erase成员函数

②删除满足条件的所有对象

  • vector,string,deque     erase_remove_if
  • list               list::remove_if
  • 标准关联容器          remove_copy_if到一个临时空间,再swap或者写一个循环来遍历容器中的元素,以后缀迭代器传给erase

③循环内部的注意点

序列容器每次调用erase时,要用它的返回值更新迭代器

for(auto i = v.begin();i!=v.end();;){    if(need_delete(*i)) i = v.erase(i);    else ++i;}

关联容器以后缀传给erase

for(auto i = a.begin();i!=a.end();;){    if(need_delete(*i)) a.erase(i++);    else ++i;}

Item10

了解allocator的约定和限制

由于光靠T无法配置list的alloc,所以要重绑使之可以按ListNode< T >进行内存分配

Item11

理解自定义allocator的合理用法

Item12

切勿对STL容器的线程安全性有不切实际的依赖

必须手工做同步控制,也可以用{}将代码段包围,开始时用RAII技术来使用Lock类

0 0
原创粉丝点击