Effective STL(1)——STL容器1-2
說明:由於最近在使用STL寫演算法練習,所以先來把Effective STL這本短小精悍的書,過一遍,讓自己對STL理解更深一點,選擇更合適的容器,能把程式碼寫得規範一點
第1條:慎重選擇容器型別
1.容器的分類
(1)C++標準庫的分類
注意:array和forward_list,無序容器都是C++11引入的新標準(《參考C++Primer第五版》),我此處將不再使用《Effective STL》中作者的分類
(2)作者的分類
連續記憶體容器:array,vector,string,dequeue,rope
元素存放在一塊或多塊(動態分配的)內;
每塊記憶體中存有多個元素;
當有新元素插入或已有元素被刪除時,同一記憶體塊中的其他元素要向前或向後移動,為新元素讓出空間,或填充被刪除元素所留下的空隙
這種移動影響效率和異常安全性
基於節點的容器:list,forward_list,關聯容器(包括有序和無序,有序容器的實現方式是平衡樹,雜湊容器使用其他基於節點的實現)
每個(動態分配的)記憶體塊存放一個元素;
容器中元素的插入或刪除隻影響到指向節點的指標,而不影響節點本身的內容,所以當有插入和刪除操作時,元素的值不需要移動
2.作者的建議
(1)如果需要在容器的任意位置插入新元素,就選用序列容器,關聯容器做不到
(2)如果不關心容器中的元素是排序的,則可以使用無序關聯容器,否則,避免使用無序關聯容器
(3)如果選擇的容器是標準C++的一部分,就避免使用rope
(4)如果需要使用隨機訪問迭代器,則對容器的選擇就被限定為vector,dequeue,string;
如果需要使用雙向迭代器,就避免使用forward_list和雜湊容器中的一個常見實現
(5)當發生元素的插入和刪除是,避免移動容器 中原來的元素很重要的話,避免使用連續記憶體的容器
(6)容器中的資料佈局如果需要和C相容,那就只能選擇vector
(7)如果元素查詢的速度是關鍵的考慮因素,就要考慮使用無序關聯容器,排序的vector,有序的關聯容器
(8)如果介意容器內部使用引用計數技術,就避免使用string和rope,可以考慮使用vector<char>
(9)如果對於插入和刪除操作,需要使用事物語義(回滾的能力),那麼需要使用基於節點的容器;
如果對多個元素的插入操作需要事物語義,需要選擇list,對於希望編寫異常安全程式碼的程式設計師,事物語義尤其重要
(10)需要使迭代器,指標或引用變為無效的次數最少的話,就要使用基於節點的容器,對於這類容器,只有迭代器,指標,引用指向了一個你正在刪除的元素才會失效
(11)swap操作會使string和array迭代器,指標和引用變為無效
(12)如果序列容器的迭代器是隨機訪問型別,而且只要沒有刪除操作發生,且插入操作發生在容器的末尾,則指向資料的指標和引用就不會變為無效,這種情形選擇deque,deque是唯一的,迭代器可能變為無效但指標和引用不會變為無效的STL標準庫容器
3.作者提到的概念補充(待補充連結)
(1)rope
(2)引用計數技術
(3)事物語義