boost库中的 circular_buffer顾名思义是一个循环缓冲器,其 capcity是固定的当容量满了以后,插入一个元素时,会在容器的开头或结尾处删除一个元素。
circular_buffer为了效率考虑,使用了连续内存块保存元素
- 使用固定内存,没有隐式或者非期望的内存分配
- 快速在circular_buffer头或者尾部插入,删除元素,并且是常量时间复杂度
- 常量时间访问元素
- 适合实时和对性能要求苛刻的应用
circular_buffer头部和尾部都可以写入,内部使用了两个指针first,last来操作写入。
在初始化时候,first,last都指向了固定申请内存的开始。假定申请固定的buffer元素为N个。
buffer [0] [1] [2] …[] [n-2] [n-1]
|
first
last
当不断使用push_back填充buffer,如下显示的是插入了n-1个元素,last始终指向下一个要插入的位置
buffer [0] [1] [2] …[] [n-2] [n-1]
| |
first last
当插入了n个元素,队列满时last指针回转到头部,又与first指针相等了(如果没有使用pop_front读取过元素)。
buffer [0] [1] [2] …[] [n-2] [n-1]
|
first
last
这时候再插入元素,first指向的元素buffer[0]就要被覆写了。
buffer [0] [1] [2] …[] [n-2] [n-1]
|
first
last
如上first指针也改变了,buffer[0]已经是最新的元素,buffer[1]才是最老的元素。
push_front与之类似,只不过是移动first指针插入数据。
#include<iostream>
using namespace std;
#include<boost/circular_buffer.hpp>
using namespace boost;
int main()
{
// 定义并初始化一个循环缓冲区
circular_buffer<int> cb(3);//容量为3
cout << cb.capacity() << endl; // 3
cout << cb.size() << endl; // 0
cb.push_back(1);//从尾部插入
cb.push_back(2);//
cb.push_back(3);//容量已满
cout << cb.capacity() << endl; // 3
cout << cb.size() << endl; // 3
//cb.push_front(1);//从头插入
//cb.push_front(2);//
//cb.push_front(3);//容量已满
for (int i = 0; i < cb.size(); ++i) cout << cb[i] << " ";
cout << endl;
//容量已满,尾部插入,踢出头部元素
cb.push_back(4);
for (int i = 0; i < cb.size(); ++i) cout << cb[i] << " ";
cout << endl;
//容量已满,头部插入,踢出尾部元素
cb.push_front(5);
for (int i = 0; i < cb.size(); ++i) cout << cb[i] << " ";
cout << endl;
cb.pop_back();//删除尾部的元素
for (int i = 0; i < cb.size(); ++i) cout << cb[i] << " ";
cout << endl;
cb.pop_front();//删除头部的元素
for (int i = 0; i < cb.size(); ++i) cout << cb[i] << " ";
cout << endl;
return 0;
}
可能适用的场景
- 可存储最新接收到的samples,当更新的samples到来,覆写最老的元素
- 可用作底层容器实现固定大小buffer
- 可作为一种cache,保存一定数量的最新插入的元素
- 高效的固定大小先进先出队列
- 高效的后进先去队列,当队列满时,移除最老的元素(也就是第一个插入的元素)