I would like to design an elegant yet efficient circular buffer of integers. I have designed a FIFO type circular buffer in C++(11)- starting with the class header (declaration) as follow:
[cyclicBuffer.hpp]:
#ifndef __CyclicBuff_HPP
#define __CyclicBuff_HPP
#pragma once
class CyclicBuffer
{
public:
CyclicBuffer(int buffSize);
~CyclicBuffer();
void setChar(char c);
char getChar();
void clearCycBuff(int buffSize);
private:
char *buffer;
int bufferSize;
int head; // index for the top of the buffer
int tail; // indes for the bottom of the buffer
};
#endif
implementation of the class is as following: [cyclicBuffer.cpp]:
#include "stdafx.h"
#include "cyclicBuffer.hpp"
#include <iostream>
//using namespace std;
CyclicBuffer::CyclicBuffer(int buffSize)
{
head = 0;
tail = 0;
bufferSize = buffSize;
buffer = new char[bufferSize];
std::cout << "Buffer initated successfully\n";
/*
{
std::cout << "Buffer was not created\n driver exiting...\n";
// return -1;
}*/
}
CyclicBuffer::~CyclicBuffer()
{
delete buffer;
std::cout << "Buffer destroyed successfully\n";
}
void CyclicBuffer::clearCycBuff(int buffSize) //not used , has no meaning to set '0'
{
head = 0;
tail = 0;
for (int i = 0; i <= buffSize; i++)
buffer[i] = '0';
}
void CyclicBuffer::setChar(char c)
{
//std::cout << "head: " << head << '\n';
head %= bufferSize;
buffer[head] = c;
head++;
}
char CyclicBuffer::getChar(void)
{
//std::cout << " tail:" << tail<<'\n';
tail %= bufferSize;
return buffer[tail++];
}
Finally, testing the class by an instance as follow:
// CyclicBufferMain.cpp : Defines the entry point for the console
// application.
#include "stdafx.h"
#include <iostream>
#include "cyclicBuffer.hpp"
#define SIZE 32
int main(void)
{
CyclicBuffer aBuffer(SIZE);
for (int i = 0; i < SIZE*1.5; i++)
aBuffer.setChar((char)(i+45));
for (int i = 0; i < SIZE ; i++)
std::cout << aBuffer.getChar() << ' ';
std::cout << '\n';
return 0;
}
for the given main function the result will be like this:
My question: is this class is efficient enough for low-rate uC ? (targeting to Atmel, RISC type or low performance ARM uC)
Regarding @Toby Speight: Thanks for your helpful comments and advices - few questions for you:
(1) when I did delete instead delete [], did I make a 'memory leak'? why MS VStudio (2015) didn't warn me?
(2) I would change the CyclicBuffer::clearCycBuff() member function to use buffer[i] = 0; (instead buffer[i]='0';) to clear the buffer's values.
(3) Why need to drop the commented-out code?
(4) You used uniform initializer at the constructor - is it big difference as to what I did using regular variable assignments at the constructor ?
(5) I know 'size_t' is it a specialize typedef that exists at the GNU and MS compilers but would have a problem using it when porting the code to a specific target which could not have such typedef ?
Thanks.
head == tail
you cannot know whether a circular buffer is empty or full. \$\endgroup\$(head - tail + size) % size
calculation to determine how many items there are in the buffer. \$\endgroup\$#pragma once
. \$\endgroup\$delete
todelete []
\$\endgroup\$