Effective STL:第二部分 容器

第二部分 vector和容器



第十三條:vector和string優先於動態分配的數組

當你決定用new來分配內存時,將承擔以下責任:

n  你必須確保以後會有人調用delete來刪除所分配的內存,否則將導致資源泄露。

n  你必須確保調用了正確的delete形式。比如單個對象調用delete;分配了數組,則調用delete[]。

n  你必須確保只delete了一次。如果一次分配被多次delete,結果也是不確定的。

如果使用vector和string,則可以減少以上的擔憂。

如果你使用的string是以引用計數來實現的,而又在多線程的環境中,可以考慮以下幾種做法:

n  檢查庫實現,看看是否可以禁止引用計數。這種方法不可移植。

n  尋找或開發一個不適用引用計數的string實現。

n  考慮使用vector<char>而不是string,會丟失使用string的成員函數的機會,但可以通過stl算法實現。



第十四條使用reserve來避免不必要的分配。

Vector和的string的自動增長是這樣實現的:

n  當容器容量不足時,分配一塊大小爲當前容量+max(當前容量,新增容量) 的新內存。大多數時候,都是每次以2的倍數增長,即容量需要擴張時,它們的容量加倍。

n  把容器的所有元素從舊的內存複製到新的內存。

n  析構掉舊內存中的對象

n  釋放舊內存

因此,容器的自動增長是會很耗時的。使用reserve能避免容器不必要的重複分配。主要有兩種方式:

n  若能確切知道或大概預計容器中最終會有多少元素,則可以使用reserve。

n  先預留足夠大的空間,然後,當把所有數據都加入以後,去除多餘的容量。可以考慮使用“swap技巧“(見17條)。


第十五條 注意string實現的多樣性

幾乎每個string實現都包含以下信息:

n  字符串的大小

n  用於存儲該字符中的字符的內存的容量

n  字符串的值

n  它的分配子的一個拷貝,這個字段是可選的

n  對數的引用計數。

String的實現比咋看上去有更多的自由度;同樣明顯的是,不同的實現以不同的方式利用了這種設計上的靈活性。這些區別總結如下:

n  String的值可能會被引用計數

n  String對象大小的範圍可以是一個char*指針的大小的1-7倍

n  創建一個新的字符串值可能需要零次,一次或兩次動態分配內存

n  String對象可能共享,也可能不共享其大小和容量信息。

n  String可能支持,也可能不支持針對單個對象的分配子

n  不同的實現對字符內存的最小分配單位有不同的策略。

其實stl也有很多實現版本,每個版本的string實現都是不太一樣的。以後會再找一個string實現源碼具體分析。



第十六條瞭解如何把vector和string數據傳給舊的API

Vector和string的數據傳送到舊API方式:

n  vector保證和數組具有同樣的佈局,可以直接把vector中的數據當做數組來對待。&V[0]即數組的首地址指針。反之亦然,可以將數組元素直接複製到vector的內存地址。

n  String提供c_str()函數來返回一個指向字符串的值的指針,且可用於C。因爲string中的數據不一定是存儲在連續的內存中,而且不一定以空字符結尾。所以不能隨便修改指針指向內存的值,特意用顯式調用作爲提醒。

n  對於其他類型的stl容器,可以將數據先拷貝到vector,用vector作爲中介與舊API相互傳送數據

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章