有时候我们需要固定大小的一个类似数组的东西,存储比如一个用户最近10天的留言记录这些东西,但是又想实现随机访问,也就是支持下标的操作,list肯定是不适合的,因为它不支持随机访问。当然我们可以用vector或者deque做类似的模拟封装,但是这样比较麻烦,boost库提供了一个circular_buffer,包含了stl deque和vector的几乎所有功能,而且可以指定大小。如果其中的元素的数目达到容量的上限时,circular_buffer就会对头部或者尾部的元素进行逐出。到底是逐出头部还是尾部的元素,就要看用户追加元素使用的方法是push_back还是push_front了。
circular_buffer的示意图如下:
circular_buffer元素的下标从0->n - 1依次增大(begin处为0, end - 1处为n - 1)。因为circular_buffer的总容量大小是规定的,如果达到容量上线以后,用户如果还是调用push_back方法压入元素,那么原来begin处的元素就会被覆盖,原来begin + 1处的元素成为新的begin。push_front也差不多是这样。
下面通过一个实例简单说明circular_buffer的使用:
#include <iostream>
#include <limits>
#include <boost/circular_buffer.hpp>
using namespace std;
using namespace boost;
void print(const circular_buffer<int>& nums) {
for (int i = 0; i < nums.size(); ++i) {
cout << nums[i] << " ";
}
cout << endl;
}
int main(int argc, char* argv[]) {
circular_buffer<int> nums(5); //声明一个总容量为5的circular_buffer
nums.push_back(1);
nums.push_back(2);
nums.push_back(3);
nums.push_back(4);
nums.push_back(5);
print(nums);
nums.push_back(6);
print(nums);
nums.push_front(8);
print(nums);
nums[3] = 9;
print(nums);
nums.pop_back();
print(nums);
nums.pop_front();
print(nums);
return 0;
}
运行的结果如下:
1 2 3 4 5 //容量为5的circular_buffer中现在有5个元素了
2 3 4 5 6 //push_back(6)以后,原来下标为1的元素被覆盖掉,2成为下标为0的元素,原来后面的元素下标依次减小1
8 2 3 4 5 //push_front(8)以后,原来最后面的元素6被挤掉了,8成为下标为0的元素,原来后面的元素下标依次加1
8 2 3 9 5 //nums[3] = 9, 可以通过随机下标修改元素
8 2 3 9 //pop_back, size减少1
2 3 9 //pop_front, size减少1
除了下标操作,circular_buffer也支持迭代器,扩容这些操作,详细情况可以参见:
http://www.boost.org/doc/libs/1_48_0/libs/circular_buffer/doc/circular_buffer.html