STL之“要”(一)
来源:互联网 发布:数据库原理是什么 编辑:程序博客网 时间:2024/06/10 03:13
这篇博文是《effective STL》的读后感。Bow to Scott。
1、 要多使用vector::reserve(size_t n),以减少不必要的拷贝。
vector::reserve(size_t n)在标准(http://www.cplusplus.com/reference/stl/vector/reserve/)里的解释是:vector将预存n个元素空间,当容器满时,才会执行扩张操作。另外,这一技巧特别适用于从文件中取元素。
#include <iostream>#include <fstream>#include <vector>using namespace std;int main (){ vector<int> content; size_t filesize; ifstream file ("test.bin",ios::in|ios::ate|ios::binary); if (file.is_open()) { filesize=file.tellg(); content.reserve(filesize); file.seekg(0); while (!file.eof()) { content.push_back( file.get() ); } // print out content: vector<int>::iterator it; for (it=content.begin() ; it<content.end() ; it++) cout << hex << *it; } return 0;}2、 要用empty()来代替检查size()是否为0。
对于大多数的容器,size()时间复杂度是常数,但对于一些容器,比如list,就是线性的。造成这种情况的原因是与splice函数的折中。
3、 要尽量使用区间成员函数代替它们的单元素兄弟。
总之尽量少自己写循环,多用assign和insert函数的应用。具体理由和一个面试题——将一个字符串中的空格替换为“%20”——很像。另外作者问了一个经典问题:给定两个vector,v1和v2,使v1的内容和v2的后半部分一样的最简单方式是什么?
v1.assign(v2.begin() + v2.size() / 2, v2.end()); v.insert(v.begin(), data, data + numValues);4、当使用new得的指针的容器时,要在销毁容器前delete那些指针。
本条款是为了防止内存泄露。手工delete太繁了,然而除非使用引用计数器,很难实现自动回收(见《effective STL》中的讨论)。很开心C++11标准引入了shared_ptr;但是使用shared_ptr要注意相互引用造成死锁的问题(采用weak_ptr解决,有兴趣的童鞋可以查查,就不在这讨论了)。
5、删除顺序容器中的元素时要考虑选择erase-remove或erase-remove_if。
顺序容器中,remove并不真正地将元素删除,而是将其放到容器的尾部。erase是真正删除元素。但注意,list的删除比较特殊,直接调用remove
(1)将容器中值为1963的值全部删除:
对于顺序容器:c.erase(remove(c.begin(), c.end(), 1963),c.end());
对于list: c.remove(1963);
(2)将顺序容器中满足此函数为true的值删除:bool badValue(int x)
对于顺序容器:c.erase(remove_if(c.begin(), c.end(), badValue),c.end);
对于list: c.remove_if(badValue);
6、如果决定用new生成对象序列,那么最好用vector或者string进行管理。(而不是数组)
vector和string管理自己的内存。当元素添加到那些容器中时它们的内存会增长,而且当一个vector或string销毁时,它的析构函数会自动销毁容器中的元素,回收存放那些元素的内存。
7、要记得用swap技巧来休整过剩容量
有时候,如果你的vector有时候容纳了10万个的可能的候选元素,但后来它只挑出10个,其他的erase掉,但vector的容量会继续保持在至少100,000。这无疑是一种浪费。可以采用这样的技巧来“收缩到合适(shrink to fit)”:
vector<Contestant>(contestants).swap(contestants);
8、要为指针的关联容器指定比较类型
我们经常用map或者set存指针。而关联容器有隐含的比较仿函数,例如set<string*> ssp其实是set<string*, less<string*>, allocator<string*> > ssp。当我们想按顺序输出存放的值时,应当为其指定比较仿函数。(或者说养成好习惯,坚持为指针的关联容器指定比较类型)。比如:
struct StringPtrLess:public binary_function<const string*,const string*,bool> { bool operator()(const string *ps1, const string *ps2) const { return *ps1 < *ps2; }};typedef set<string*, StringPtrLess> StringPtrSet;StringPtrSet ssp;
这样用迭代器访问ssp中元素时就是按顺序访问的。
9、永远让比较函数对相等的值返回false
如上一条中的<号不能定为<=,主要原因是等价的判定会因=出现问题,不深究,牢记。
10、当查找速度真的很重要时,可以考虑排序的vector或者hash代替关联容器
这个不多说,面试题或实际应用见过太多11、要根据实际情况仔细选择map::operator[]和map-insert
虽然二者的效果一样,但在不同情况下效率是不一样的。主要问题在于[]会新开辟临时变量。
结论是:如果你要更新已存在的map元素,operator[]更好,但如果你要增加一个新元素,insert则有优势。
- STL之“要”(一)
- STL之List(一)
- STL学习笔记之 (一)模版
- C++STL之algorithm(一)
- STL之map实现(一)
- STL学习之(一)
- (一)STL之list
- STL之迭代器事例一
- STL源码剖析之第三章读后笔记(一)
- c++ 工程基础之STL系列 (一) vector
- STL之vector的使用一(初始化vector)
- STL学习笔记之容器--vector(一)
- STL学习笔记之容器--list(一)
- STL学习笔记之容器--deque(一)
- 3.5 STL之vector的使用一(初始化vector)
- STL之Vector(一):Vector的基本用法
- STL 源码分析之string(一)基础篇
- STL学习(一)
- String to Integer (atoi)
- matlab 画图
- 获取网卡地址
- 十一国庆C++小总结
- WebRTC体系结构
- STL之“要”(一)
- 问题汇总
- Bitmap和Drawable相互转换方法
- Android学习笔记(八) —— 手机页面的转换 — setContentView的应用
- cocos2d-x在windows平台HelloWorld解析-沈大海cocos2d-x教程之3
- JQuery获取浏览器窗口宽高,文档宽高的代码
- vc6<实用>开发activex并发布全攻略(三)
- 网络扫盲
- Spring MVC中配置Kaptcha验证码