• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
thankgoodness
博客园    首页    新随笔    联系   管理    订阅  订阅

STL里的数据结构

数据结构  

描述 

实现头文件

向量(vector)

连续存储的元素

<vector>

列表(list) 

 由节点组成的双向链表,每个结点包含着一个元素

<list>

双队列(deque)

 连续存储的指向不同元素的指针所组成的数组

  <deque>

集合(set) 

 由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序          

 <set>

多重集合(multiset)

 允许存在两个次序相等的元素的集合

 <set>

 栈(stack) 

 后进先出的值的排列

 <stack>

  队列(queue)  

 先进先出的执的排列

  <queue>

 优先队列(priority_queue)

 元素的次序是由作用于所存储的值对上的某种谓词决定的的一种队列

 <queue>

  映射(map)

 由{键,值}对组成的集合,以某种作用于键对上的谓词排列

 <map>

 多重映射(multimap)

 允许键对有相等的次序的映射 

   <map>


1. string.empty() 不是用来清空字符串,而是判断string是否为空,清空使用string.clear();

2. string.find等查找的结果要和string::npos比较,而不是和-1比较。(各个平台可能不同)

3. 将string转为char * ,用char * t = (char *)s.c_str() ,而不是 char *t =s.begin() 或者 char *t = &s[0] 或者 char *t =s.data();

4. 不要用错string.find ,string::find_first_of ,find和find_first_of有本质区别
find是查找子串在string出现的位置
find_first_of是查找第一个匹配目标字符串任何一个字符出现的位置。
(大多数的时候,需要的是find)

5. 用swap技巧来移去string(vector)多余的空间
vector<int> v ;
...
vector<int>(v).swap(v);

6. 用vector<char>来储存二进制流

7. 了解各种储存bool的优缺点
vector<bool> 第一,它不是一个真正STL容器,第二,它并不保存bool类(Effective STL 18条)
deque<bool> 不连续
vector<char> 太浪费
bitset 不能动态增长
boost::dynamic_bitset 不是标准

8. vector resize()和reserve()分别和size和capacity对应,不要搞错

9. vector 的at方法会进行边界检查,[]操作符则不会

10. 使用iterator的时候,自增或者自减,多使用++iter ,--iter的格式。

11. std::mem_fun/std::mem_fun_ref可以将成员函数用来for_each等方法。
std::vector<Employee> emps;
std::for_each(emps.begin(), emps.end(),
std::mem_fun_ref(&Employee::DoStandardRaise);

std::vector<Employee*> emp_ptrs;
std::for_each(emp_ptrs.begin(), emp_ptrs.end(),
std::mem_fun(&Employee::DoStandardRaise));

12. 如何删除?
vector:
vector<int> v;
v.erase(remove(v.begin(), v.end(), 99), v.end());

list:
list<int> li;
li.remove(99);

13. 尽量用成员函数代替同名的算法

14. 循环中删除map元素的写法
typedef map<int,int> mymap;
typedef map<int,int>::iterator myiter;
mymap m; m[1] = 2; m[2] = -1; m[3] = 3; m[4] = 0; m[5] = -5; m[6] = 1;
myiter iter = m.begin();

while(iter!=m.end()) {
if(iter->second<0)
m.erase(iter++);
else
++iter;
}

15. 从ifstream读出一行到string,使用std::getline(ifstream的成员函数getline做不到)

16.警惕string的引用记数技术实现带来的潜在问题

string greet("Hello, world");
string hi(greet);
char *ptr = (char *)hi.c_str();
ptr[0] = 'h';
两个字符串都被修改。

在多线程之间引用多个有关系的string,可能导致引用计数失效,造成多次删除,或者memory leak.
保险的做法是:
string s1("hello") ; string s2 (s1.c_str()); //force copy


17.自定义类放入stl容器中,应注意实现安全的copy ctor和assign operator.尤其是含有指针的class,避免多次删除

18.避免iterator失效,不提取无效的iterator
比如:
vector<int> iv;
vector<int>::iterator end = iv .end();
for(int i=0;i<10;++i)
iv.insert(end,i);
会crash ,因为end指针,随着insert后可能失效
改为:
vector<int> iv;
for(int i=0;i<10;++i)
iv.insert(iv.end(),i);
或者:
vector<int> iv;
for(int i=0;i<10;++i)
iv.push_back(i); //prefer


19. 不要把std::auto_ptr用于数组指针
auto_ptr<int> p(new int[10]); //maybe cause memory leak

20. 不要直接修改set,map的键值,如果要修改,先erase,再insert.

21. 多线程下,几个线程如果共同操作一个容器,安全性(锁)应该由用户自己来实现,stl不保证这一点
例如,一个多线程安全的deque
template<typename T,class ThreadModel=MultiThread>
class CDequePool:private ThreadModel {
private:
std::deque<T> m_clDeque;
//.....
public:
bool PutData(const T &data)
{
Lock();
m_clDeque.push_front(data);
Unlock();
return true;
}
//....
}
posted @ 2008-05-15 15:47  宇晨  阅读(748)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3