Effective STL(1)

来源:互联网 发布:linux mint vs ubuntu 编辑:程序博客网 时间:2024/06/17 21:57

走马观花式地看了一遍《Effective STL》,书很经典,需要再多看几遍,先把这次阅读时候记下的笔记贴出来。

1.      标准STL序列容器:vector、string、deque和list

标准STL关联容器:set、multiset、map和multimap

Vector,list和deque提供给程序员不同的复杂度,因此应该这么用:vector是一种可以默认使用的序列类型,当很频繁地对序列中部进行插入和删除时应该用list,当大部分插入和删除发生在序列的头或尾时可以选择deque这种数据结构。

2.通过自由地对容器和迭代器类型使用typedef,因此不要这么写:

Class Widget{……};

Vector<Widget> rw;

Widget   bestWidget;

Vector<Widget>::iterator I =find(rw.begin(), rw.end(), bestWidget);

 

要这么写:

Typedef vector<Widget>  WidgetContainer;

Typedef WidgetContainer::iteratorWCIterator;

WidgetContainer cw;

Widget bestWidget;

WCIterator I = find(cw.begin(), cw.end(),bestWidget);

3.用empty来代替检查size()是否为0

4.尽量使用区间成员函数代替它们的单元素兄弟

V1.assign(v2.begin() + v2.size()/2,v2.end());

V1.insert(v1.end(),v2.begin()+v2.size()/2,v2.end());

区间插入:insert(iterator position,//区间插入的位置

InputIteratorbegin,//插入区间的起点

InputIteratorend)//插入区间的终点

关联容器使用它们的比较函数来决定元素要放在哪里,所以它们省略了position参数

Void container::insert(InputIterator begin,InputIterator end);

区间删除:每个标准容器都提供了一个区间形式的erase,但是序列和关联容器的返回类型不同。序列容器提供了这个:

Iterator container::erase(iterator begin,iterator end);

而关联容器提供这个:

Void container::erase(iterator begin,iterator end);

区间赋值:所有标准列容器都提供了区间形式的assign:

Void container::assign(InputIterator begin,InputIterator end);

5.C++里的一条通用规则—几乎任何东西都可能被分析成函数声明。如

Class Widget{};//假设Widget有默认构造函数

Widget w();//这里并没有声明一个叫做wWidget,它声明了一个叫做w的没有参数且返回Widget的函数。

6.当使用new得指针的容器时,记得在销毁容器前delete那些指针

Void doSomething()

{

Vector<Widget*> vwp;

For(vector<Widget*>::iterator I =vwp.begin(); I != vwp.end(); ++i)

{

Delete *I;

}

}

使用智能指针:

Void dosomething()

{

Typedef boost::shared_ptr<Widget>SPW;

Vector<SPW> vwp;

For(int I = 0; i<Some_MAGIC_NUMBER;++i)

{

Vwp.push_back(SPW(new Widget));

}

}

7当你拷贝一个auto_ptr时,auto_ptr所指向的对象的所有权会转移给拷贝的auto_ptr所指向的对象,被拷贝的auto_ptr则为NULL;

8.在删除选项中仔细选择

c.erase(remove(c.begin(),c.end(),1963),c.end())//当c时vector,string或deque时,erase-remove惯用法是去除特定值的元素的最佳方法

这方法也适用于list

c.remove(1963);

对于关联容器,解决问题的适当方法是调用erase:

c.erase(1963);//这不仅是正确的,而且很高效,只花费对数时间。序列容器的基于删除的技术需要线性时间。

9.线程安全

10.使用reserve来避免不必要的重新分配

Size()告诉你容器中有多少元素。它没有告诉你容器为它容纳的元素分配了多少内存。

Capacity()告诉你容器在它已经分配的内存中可以容纳多少元素。

Resize()强制把容器改为n个元素。调用resize之后,size将会返回n.如果n小于当前大小,容器尾部的元素会被销毁。如果n大于当前大小,新默认构造的元素会添加到容器尾部。如果N大于当前容量,在元素加入之前会发生重新分配。

Reserve()强制容器把它的容量的改为至少N,提供的n不小于当前大小。这一般强迫进行一次重新分配,因为容量需要增加。


0 0
原创粉丝点击