1. 慎重选择容器
标准STL序列容器: vector, string, deque, list.
标准STL关联容器:set, multiset, map, multimap
vector<char> 作为string的替代
vector 作为标准关联容器的替代
2.不要试图编写独立于容器类型的代码
class Widget{};
typedef vector<Widget> WidgetContainer;
typedef WidgetContainer::iterator WCIterator;
WidgetContainer cw;
Widget bestWidget;
WCIterator = find(cw.begin(), cw.end(), bestWidget);
3. 确保容器中对象拷贝正确高效
vector<Widget> vw;
class SpecialWidget: public Widget{};
SpecialWidget sw;
vw.push_back(sw); //派生类特有部分在拷贝时被丢掉了
4. 调用empty 而不是检查size()是否为0
理由:empty对所有标准容器都是常数时间的操作,而对于一些list实现,size耗费线性时间。
list 不知道自己含有多少元素,求size需要线性遍历。
假如每次更新list时保持size更新,则那么list的更新链接过程就需要线性时间,为了使得list链接耗费常数实践,因此选择不实时保存size大小而通过遍历后获得。
5. 区间成员函数优先于与之对应的单元素成员函数
v1.assign(v2.begin()+v2.size()/2, v2.end());//assign直接覆盖原有v1的值
//区间创建
container::container(InputIterator begin,//区间开始
InputIterator end);//区间结束
//区间插入
void container::insert(iterator position,
InputIterator begin,
InputIterator end);
//区间删除 erase-remove方法
iterator container::erase(iterator begin, iterator end);//指向被删除元素之后,存在性能大开销
void container::erase(iterator begin, iterator end);
//区间赋值
void container::assign(InputIterator begin, InputIterator end);
6.当心C++编译器最烦人的分析机制
//C++普遍规律 尽可能解释为函数声明
ifstream dataFile("ints.dat");
list<int> data(istream_iterator<int>(dataFile), istream_iterator<int>()); //分析为data函数参数为...
list<int> data((istream_iterator<int>(dataFile)), istream_iterator<int>()); //加上括号表示为函数参数而非函数声明
istream_iterator<int> dataBegin(dataFile);
istream_iterator<int> dataEnd;
list<int> data(dataBegin, dataEnd);
7.容器中元素new和delete需要对应
void doSomething(){
vector<Widget*> vwp;
for(vector<Widget*>::iterator i = vwp.begin(); i!=vwp.end(); ++i)
{
delete *i;//new对应delete
}
}
template<typename T>//函数子
struct DeleteObject :public unary_function<const T*, void>{
void operator()(const T* ptr) const
{
delete ptr;
}
};
void doSomething(){
vector<Widget*> vwp;
for_each(vwp.begin(), vwp.end(), DeleteObject<Widget>());//使用函数子来删除指针元素
}
8. 切勿创建包含auto_ptr的容器对象
9. 慎重选择删除元素的方法
Container<int> c;
//对于连续内存的容器(vector, deque, string)
c.erase(remove(c.begin(), c.end(), 1963), c.end());
//对list
c.remove(1973);
//对于关联容器
c.erase(1963);
//判别式删除
bool badValue(int);
c.erase(remove_if(c.begin(), c.end(), badValue), c.end());//...
c.remove_if(badValue);//list
AssocContainer c;
for(AssocContainer:iterator i=c.begin();i!=c.end(); )
{
if(badValue(*i)) c.erase(i++);//防止删除后产生迭代器失效
else ++i;
}
10. 了解分配子的约定和限制
11.
12.切勿对STL容器的线程安全性有不切实际的想法