歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C++ 頭文件系列(vector)

C++ 頭文件系列(vector)

日期:2017/3/1 9:06:10   编辑:Linux編程

簡介

vector頭文件包含vector的類模版以及該模版的顯示特化版本vector< bool >

vector是C++容器庫中非常通用的一種容器,如果你不知道該決定使用哪一種容器,或者沒有足夠的理由使用其它容器,那麼就用它,沒錯的!

從整體上來看,vector就像是一種動態數組,它擁有數組的所有功能並且能夠動態增長。 它主要有以下性質:

  • 序列性容器
  • 動態增長
  • 可定制的內存分配策略

內存分配器

如果在一些特殊的應用場景中,默認的內存分配策略拉低了運行效率,這時候自定義的內存分配其就會站出來幫你了~

內存分配器主要用在STL Containers中,為容器合理的分配內存,默認使用位於memory頭文件中的allocator。 我們也可以自定義內存分配器,但需要滿足一些要求:

Other allocators may be defined. Any class Alloc for which allocator_traits

上面這段摘錄的文字表明,任何能夠實例化allocator_traits模版並且帶有合適成員函數的類Alloc都能作為容器的內存分配器使用。 再來看allocator_traits:

The non-specialized version provides an interface that allows to use as allocator just any class that provides at least a public member type value_type and public member functions allocate and deallocate (see example).

這段話說,任何至少提供了一個公開成員類型value_type和公開成員函數allocate和deallocate的類都可以被允許作為內存分配器

總的來說,自定義一個內存分配器,你最少需要

  1. 定義value_type類型
  2. 定義allocate成員函數
  3. 定義deallocate成員函數

特殊函數

由於vector是動態數組,它的大部分設計是與array類模版類似的,這裡就不再贅述了。 我們來看看那些不一樣的的地方。

resize VS shrink_to_fit

這兩個函數是比較特別的,從字面上看它們都是改變大小為固定值。 但實際上兩者是有區別的,我們來看它們的函數原型:

void resize (size_type n);
void shrink_to_fit ();

一眼就能看出,兩者的參數不一樣:resize傳入一個數值,作為新的容器大小;而shrink_to_fit則沒有參數。 那我們不禁要問了,既然shrink_to_fit沒有指定新的容器大小,它怎麼改變呢?

這就揭示了兩者語義上的不同----一個是改變大小至給定值,另一個是縮小容器容量(capacity)至容器大小(size)。 也就是說,它們影響的是容器的兩個不同方面。 同時需要指出的是, shrink_to_fit調用發出的是請求,調用後容器容量可能被按預期縮小到容器大小了,也有可能比容器大小大;而resize調用發出的時命令,容器一定會被重新調整大小至給定值。

C接口

vector提供了一個接口以供開發者直接在內部數組(vector內部以數組實現)上直接對元素進行操作:

  • value_type* data() noexcept;

順道一提,vector與array一樣,是元素之間的內存連續的(contiguous)。

vector< bool >顯示特化

非常有意思的是vector

為什麼

為什麼會出現這樣一個特殊的模版特化呢? 因為語言支持的最小單位一般是字節(char、unsigned char),而bool的語義意味著它只需要1bit的內存。 如果用1個字節來存儲bool類型,會造成極大的內存浪費,出於內存的優化考慮,就出現了這麼一個特殊的東西。

它的原理非常簡單,就是把每個bool用1個bit來存儲,所以1個字節可以存儲8個bool(在常見的機器上)。 但是這也引出了一個麻煩的問題:在語義上,我們應該可以對bool賦值、取地址、取引用等。 但是bool等於bit這種實現方式意味著我們不能夠那樣做。 那怎麼辦了,這裡使用了一個C++典型的慣用法----代理(Proxy),它把reference成員理性定義為該代理,用這個代理來將內部bit轉換成bool。

Flip函數

該模版特化還包含了一個額外的函數----Flip。 顧名思義,就是將所有bool都“翻轉”,true -> false, false -> true。

先前提到的reference代理也有這個函數,但它是將單個bool“翻轉”。 vector< bool >類模版的flip函數可能就是通過該函數實現的。

Copyright © Linux教程網 All Rights Reserved