[ 不斷補(bǔ)充中]
1. string.empty() 不是用來(lái)清空字符串,而是判斷string是否為空,清空使用string.clear();
2. string.find等查找的結(jié)果要和string::npos比較,而不是和-1比較。(各個(gè)平臺(tái)可能不同)
3. 將string轉(zhuǎn)為char * ,用char * t = (char *)s.c_str() ,而不是 char *t =s.begin() 或者 char *t = &s[0] 或者 char *t =s.data();
4. 不要用錯(cuò)string.find ,string::find_first_of ,find和find_first_of有本質(zhì)區(qū)別
??? find是查找子串在string出現(xiàn)的位置
??? find_first_of是查找第一個(gè)匹配目標(biāo)字符串任何一個(gè)字符出現(xiàn)的位置。
??? (大多數(shù)的時(shí)候,需要的是find)
5. 用swap技巧來(lái)移去string(vector)多余的空間
?? vector<int> v ;
?? ...
?? vector<int>(v).swap(v);
6. 用vector<char>來(lái)儲(chǔ)存二進(jìn)制流
7. 了解各種儲(chǔ)存bool的優(yōu)缺點(diǎn)
vector<bool> 第一,它不是一個(gè)真正STL容器,第二,它并不保存bool類(lèi)(Effective STL 18條)
deque<bool> 不連續(xù)
vector<char> 太浪費(fèi)
bitset 不能動(dòng)態(tài)增長(zhǎng)
boost::dynamic_bitset 不是標(biāo)準(zhǔn)
8. vector resize()和reserve()分別和size和capacity對(duì)應(yīng),不要搞錯(cuò)
9. vector 的at方法會(huì)進(jìn)行邊界檢查,[]操作符則不會(huì)
10. 使用iterator的時(shí)候,自增或者自減,多使用++iter ,--iter的格式。
11. std::mem_fun/std::mem_fun_ref可以將成員函數(shù)用來(lái)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. 盡量用成員函數(shù)代替同名的算法
14. 循環(huán)中刪除map元素的寫(xiě)法
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的成員函數(shù)getline做不到)
16.警惕string的引用記數(shù)技術(shù)實(shí)現(xiàn)帶來(lái)的潛在問(wèn)題
string greet("Hello, world");
string hi(greet);
char *ptr = (char *)hi.c_str();
ptr[0] = 'h';
兩個(gè)字符串都被修改。
在多線程之間引用多個(gè)有關(guān)系的string,可能導(dǎo)致引用計(jì)數(shù)失效,造成多次刪除,或者memory leak.
保險(xiǎn)的做法是:
string s1("hello") ; string s2 (s1.c_str()); //force copy
?
17.自定義類(lèi)放入stl容器中,應(yīng)注意實(shí)現(xiàn)安全的copy ctor和assign operator.尤其是含有指針的class,避免多次刪除
18.避免iterator失效,不提取無(wú)效的iterator
比如:
vector<int> iv;
vector<int>::iterator end = iv .end();
for(int i=0;i<10;++i)
??? iv.insert(end,i);
會(huì)crash ,因?yàn)閑nd指針,隨著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用于數(shù)組指針
auto_ptr<int> p(new int[10]); //maybe cause memory leak
20. 不要直接修改set,map的鍵值,如果要修改,先erase,再insert.
21. 多線程下,幾個(gè)線程如果共同操作一個(gè)容器,安全性(鎖)應(yīng)該由用戶自己來(lái)實(shí)現(xiàn),stl不保證這一點(diǎn)
例如,一個(gè)多線程安全的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;
???}
//....
}