The C++ Standard Library备忘:第6章 STL容器

2014-01-01 22:20:39 

6、STL容器

STL容器都必須滿足那些條件。三個最核心的能力是:

  1. 所有容器提供的都是「value語意」而非「reference語意」。容器進行元素的安插動作時,內部實施的是拷貝動作,置於容器內。因此STL容器的每一個元素都必須能夠被拷貝。如果你意圖存放的物件不具有public copy建構式,或者你要的不是副本(例如你要的是被多個容器共同容納的元素),那麽容器元素就只能是指標(指向物件)。5.10.2節, p135 對此有所描述。

  2. 總體而言,所有元素形成一個次序(order)。也就是說,你可以依相同次序一次或多次巡訪每個元素。每個容器都提供「可傳回迭代器」的函式,運用那些迭代器你就可以巡訪元素。這是STL演算法賴以生存的關鍵介面。

  3. 一般而言,各項操作並非絕對安全。呼叫者必須確保傳給操作函式的引數符合需求。違反這些需求(例如使用非法索引)會導致未定義的行爲。通常STL自己不會丟擲異常。如果STL 容器所呼叫的使用者自定操作(user-definedoperations)擲出異常,會導致各不相同的行為。參見5.11.2節, p139。

6.2 Vectors

vector模塑出一個dynamic array。因此,它本身是「將元素置於dynamic array中加以管理」的一個抽象概念(圖6.1)。不過請注意,C++ Standard並未要求必須以dynamic array實作vector,只是規定了相應條件和操作複雜度。


其中,型別vector是一個定義於namespace std內的template:

namespace std {

template <class T,

class Allocator = allocator<T> >

class vector;

}

vector的元素可以是任意型別T,但必須具備assignable和copyable兩個性質。第二個template參數可有可無,用來定義記憶體模型(memory model,參 見15章)。預設的記憶體模型是C++ 標準程式庫提供的allocator。

6.2.1 Vectors的能力

​vectors 之中用於操作大小的函式有size(),empty(),max_size()(6.1.2 節,p144)。另一個與大小有關的函式是capacity(),傳回vector實際能夠容納的元素數量。如果超越這個數量,vector就有必要重新配置內部記憶體。

vector的容量之所以很重要,有以下兩個原因:

  1. 一旦記憶體重新配置,和vector元素相關的所有references、pointers、iterators都會失效。

  2. 記憶體重新配置很耗時間。

所以如果你的程式管理了和vector元素相關的references、pointers、iterators,或如果執行速度對你而言至關重要,那麽就必須考慮容量問題。

你可以使用reserve()保留適當容量,避免一再重新配置記憶體。如此一來,只要保留的容量尚有餘裕,就不必擔心references失效。

std::vector<int> v;  // create an empty 

vectorv.reserve(80);  // reserve memory for 80 elements

事實上爲了防止記憶體破碎,在許多實作方案中即使你不呼叫reserve(),當你第一次安插元素時也會一口氣分配整塊記憶體(例如2K)。如果你有一大堆vectors,每個vector的實際元素卻寥寥無幾,那麽浪費的記憶體相當可觀。

既然vectors的容量不會縮減,我們便可確定,即使刪除元素,其references、pointers、iterators 也會繼續有效,繼續指向動作發生前的位置。然而安插動作卻可能使references、pointers、iterators失效(譯註:因為安插可能導致vector重新配置)。

這裏有一個間接縮減vector容量的小竅門。注意,兩個vectors交換內容後,兩者的容量也會互換,因此下面的例子雖然保留了元素,卻縮減了容量:

template <class T>

void shrinkCapacity(std::vector<T>& v)

{

std::vector<T> tmp(v); // copy elements into a new vector

v.swap(tmp); // swap internal vector data

}

你甚至可以利用下面的述句直接縮減容量:

// shrink capacity of vector v for type T

std::vector<T>(v).swap(v);

不過請注意,swap()之後原先所有的references、pointers、iterators 都換了指涉對象;它們仍然指向原本位置。換句話說上述的shrinkCapacity()使所有references、pointers、iterators失效。












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值