基于上一个练习的改造:
#include <iostream>
#include <exception>
#include <cstring>
#include <cassert>
#include <cstdlib>
#include <stdexcept>
#define NODE_NUMBER 100
using namespace std;
typedef int TypeBuf; // 后续的改进考虑:将NODE结构体中buf 类型泛华。
typedef struct node
{
node *prev;
node *next;
//void *buf;
TypeBuf buf; //buf使用int类型作为调试
}NODE;
class ring_buff{
public:
ring_buff(int size=NODE_NUMBER)//构造函数,默认参数支持 ring_buff ring_A这样的定义
{
NODE *pNode, *pEnd, *pTemp;
pRingBuff = new NODE[size];
if (NULL==pRingBuff)
{
throw runtime_error("alloc memory failed in ring_buff construct\n");
}
memset(pRingBuff, 0, sizeof(NODE)*size);
pTemp = pRingBuff;
for(int i=0; i<size-1; i++)
{
pNode = pTemp;
pNode->next = ++pTemp;
pNode->next->prev = pNode;
pNode->buf = i+1;
//pNode->buf = (void*) malloc(NODE_BUFFER_SIZE);//buf如果使用malloc申请内存,则需要在析构函数中释放
}
head = pNode = pRingBuff;
tail = pEnd = pTemp;
pEnd->next = pNode;
pEnd->prev = --pTemp;
pNode->prev = pEnd;
cout<<"construct OK!!"<<endl;
}
bool is_full(void)
{
return tail->next == head;
}
bool is_empty(void)
{
return head->next == tail;
}
int insert_node_into_ring(NODE new_buff_list[], int size)
{
assert(new_buff_list and tail);
NODE *pTailNext = tail->next;
NODE *pNode=NULL;
int i;
for(i=0; i<size;i++)
{
pNode = &new_buff_list[i];
pNode->next = &new_buff_list[i+1];
pNode->next->prev= pNode;
pNode->buf = 888;
}
tail->next = &new_buff_list[0];
tail->next->prev = tail;
pTailNext->prev = &new_buff_list[i-1];
pTailNext->prev->next = pTailNext;
return i;
}
int write_buff(int size)
{
assert(head and tail);
int i;
for(i=0; i<size; i++)
{
if(is_full())//如果缓存满,则直接返回已写入的节点数量,而不再调用insert_node_into_ring 去插入新的节点;
//原因是如果插入新的节点,需要分配新的内存,这些内存插入到环形缓存队列后,不好管理,
//程序退出时,不方面释放 ;因此,换了一种方式:在用户使用该环形缓存队列时,队列满时,自己先申请内存并插入。如下面main的
//ring.insert_node_into_ring(new_buff_list, 10)
{
cout<<endl;
return i;
}
else
{
tail->buf = 111;
tail = tail->next;
}
}
cout<<endl;
return i;
}
int read_buff(int size)
{
assert(head and tail);
int i;
for(i=0; i<size; i++)
{
if(is_empty())
{
cout<<endl;
return i;
}
else
{
cout<<"***"<<head->buf;
head->buf = 0;
}
head=head->next;
}
cout<<endl<<endl;
return i;
}
~ ring_buff(void)
{
delete pRingBuff; //析构函数,释放堆内存
pRingBuff=NULL;
head = tail = NULL;
cout<<"destruct OK!!"<<endl;
}
void pring_list(int size=NODE_NUMBER)
{
NODE *pNode = pRingBuff;
for(int i=0; i<size; i++)
{
cout<<"--";
cout<<pNode->buf;
pNode = pNode->next;
}
cout<<endl<<"****************************************"<<endl;
}
private:
NODE *head;
NODE *tail;
NODE *pRingBuff;
};
int main(void)
{
NODE new_buff_list[10];
try{
ring_buff ring;
ring.pring_list(100);
ring.read_buff(10);
ring.pring_list(100);
ring.write_buff(10);
ring.pring_list(100);
ring.read_buff(10);
ring.pring_list(100);
ring.insert_node_into_ring(new_buff_list, 10);//插入节点是在栈上分配的内存,如果是堆上分配的内存,也需要注意释放
ring.pring_list(100);
}
catch(runtime_error &e){//打印运行异常
cout<<"exception :" <<e.what()<<endl;
}
catch(...){
cout<<"unknown exception\n";
}
return 0;
}