boost.circular_buffer簡介

很多時候,我們需要在內存中記錄最近一段時間的數據,如操作記錄等。由於這部分數據記錄在內存中,因此並不能無限遞增,一般有容量限制,超過後就將最開始的數據移除掉。在stl中並沒有這樣的數據結構,一般需要我們自己構造,常用方法如下:

  1. 用list構造,超過後把數據頭移除

  2. 用vector構造,超過後把數據頭移除

  3. 用數組構造,通過循環的方式覆蓋

這幾種方式都有各自的缺點:用list構造無法實現隨機訪問,用vector構造移動數據頭開銷較大,用數組構造需要維護數據頭指針和防止計數器溢出,計算位置和數據的移除也相對較麻煩。

當然,這些都不是無法解決的問題,就是稍微麻煩點。不過現在boost直接提供了一個circular_buffer類可以實現這一操作,它的接口基本上和vector類似,但它有容量限制,實現方式也稍微有點不同:

circular_buffer內部也是用一塊連續內存保存數據,元素的下標從0->n - 1依次增大(begin處爲0, end - 1處爲n - 1)。如果達到容量上限,繼續push_back方法壓入元素時,原來begin處的元素就會被覆蓋,原來begin + 1處的元素成爲新的begin,push_front功能類似。

也就是說,circular_buffer的內部還是通過數組來實現,只不過給我們做好了封裝工作,提供了vector類似的接口,用起來非常簡便。如下是boost文檔是的例子:

    // Create a circular buffer with a capacity for 3 integers.
    boost::circular_buffer<int> cb(3);

    // Insert some elements into the buffer.
    cb.push_back(1);
    cb.push_back(2);
    cb.push_back(3);

    int a = cb[0]; // a == 1
    int b = cb[1]; // b == 2
    int c = cb[2]; // c == 3

    // The buffer is full now, pushing subsequent
    // elements will overwrite the front-most elements.

    cb.push_back(4); // Overwrite 1 with 4.
    cb.push_back(5); // Overwrite 2 with 5.

    // The buffer now contains 3, 4 and 5.
    a = cb[0]; // a == 3
    b = cb[1]; // b == 4
    c = cb[2]; // c == 5

    // Elements can be popped from either the front or the back.
    cb.pop_back(); // 5 is removed.
    cb.pop_front(); // 3 is removed.

    int d = cb[0]; // d == 4

雖然circular_buffer這種功能並不難實現,但既然boost給我們提供了一個好用的準標準庫,就不要重複造輪子了。

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