Hello,
This is the first time that I’ve used the keyword template so I’m not sure I’m using it correctly.
I’ve modified Konstantin Gruzdev’s CArrayRing buffer found here: https://www.mql5.com/en/code/1340 to allow any type to be added to the buffer. However,
when i use it, the MT4 editor crashes violently.
The code that I type is this:
CArrayRing *buffer;
buffer = new CArrayRing();
buffer.Init
and it is exactly when I enter the ( of the Init method the editor crashes.
What am I doing wrong?
Here’s my modified code:
//+------------------------------------------------------------------+
//| CArrayRing.mqh |
//| Copyright 2012, Konstantin Gruzdev |
//| https://login.mql5.com/ru/users/Lizar |
//| Revision 03 Dec 2012 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, Konstantin Gruzdev"
#property link "https://login.mql5.com/ru/users/Lizar"
//+------------------------------------------------------------------+
//| Class CArrayRing |
//| Appointment: class is designed to work with tne finite ring |
//| buffers of data. When the buffer is crowded the oldest |
//| buffer element is replaced by the newest element. Herewith, |
//| the specified number of end elements are always available. |
//| Link: http://www.mql5.com/ru/code/1340 |
//| Remark: it should also be kept in mind that the element indexing |
//| in the ring buffer is executed as in timeseries. |
//+------------------------------------------------------------------+
class CArrayRing
{
private:
template<typename T>
T m_data[]; // ring buffer of data
int m_size; // buffer size
int m_last_pos; // last buffer element position
double m_filling; // value, which used for the array filling
public:
CArrayRing();
~CArrayRing() { ArrayFree(m_data); }
template<typename T>
//--- buffer initialization method:
bool Init(int size, T value=EMPTY_VALUE);
//--- method returns the buffer size:
int Size() { return m_size-1; }
//--- method changes the ring buffer size:
bool Resize(const int size);
template<typename T>
//--- method of adding a new element to the buffer:
void Add(const T element);
//--- method returns the value of element with the specified index:
double At(const int index) const;
double operator [](const int index) const { return(At(index)); }
//--- method returns the value of the last element stored in the buffer:
double Last() const { return(m_data[m_last_pos]); }
//--- method overwrites the value of the last element in the buffer:
void Last(const T element) { m_data[m_last_pos]=element; }
template<typename T>
//--- method overwrites the value of element with the specified index:
bool Update(const T element,const int index=0);
};
//+------------------------------------------------------------------+
//| Constructor. |
//+------------------------------------------------------------------+
CArrayRing::CArrayRing() : m_last_pos(0),
m_filling(EMPTY_VALUE),
m_size(ArraySize(m_data))
{
}
//+------------------------------------------------------------------+
//| Buffer initialization method. |
//+------------------------------------------------------------------+
template<typename T>
bool CArrayRing::Init(int size, T value=EMPTY_VALUE)
{
m_last_pos=0; // last element position
m_filling=value; // value for buffer filling
m_size=ArraySize(m_data); // get size of the buffer
bool result=Resize(size); // create a buffer with the desired size
ArrayFill(m_data,0,m_size,m_filling); // fill the buffer with default values
return(result);
}
//+------------------------------------------------------------------+
//| Set the new size of the array. |
//+------------------------------------------------------------------+
bool CArrayRing::Resize(const int new_size)
{
//--- check
if(new_size<0) return(false);
//--- increase array size:
if(new_size>m_size)
{
int set_size=ArrayResize(m_data,new_size);
if(set_size<0) return(false);
//--- copy elements to restore their order:
if(set_size>m_size)
{
for(int i=m_size-1,j=set_size-1;i>m_last_pos;i--,j--)
{
m_data[j]=m_data[i];
m_data[i]=m_filling;
}
}
m_size=set_size;
//--- result:
return(true);
}
//--- reduce array size:
//--- prepare array to reduce the size:
if(new_size>m_last_pos+1)
for(i=m_size-1,j=new_size-1;j>m_last_pos;i--,j--) m_data[j]=m_data[i];
else
{
for(i=m_last_pos+1-new_size,j=0;i<=m_last_pos;i++,j++) m_data[j]=m_data[i];
m_last_pos=new_size-1;
}
//--- reduce the size:
m_size=new_size;
ArrayResize(m_data,new_size);
//--- result:
return(true);
}
//+------------------------------------------------------------------+
//| Adding a new element to the buffer. |
//+------------------------------------------------------------------+
template<typename T>
void CArrayRing::Add(const T element)
{
m_last_pos=++m_last_pos%m_size;
m_data[m_last_pos]=element;
}
//+------------------------------------------------------------------+
//| Gets the element at the specified index. |
//+------------------------------------------------------------------+
double CArrayRing::At(const int index) const
{
//--- check the index correctness:
if((index/m_size)==0)
//--- return the value of element with the specified index:
return(m_data[(m_size+m_last_pos-index)%m_size]);
//--- if the index is wrong:
return(DBL_MAX);
}
//+------------------------------------------------------------------+
//| Update the element at the specified position in the array. |
//+------------------------------------------------------------------+
template<typename T>
bool CArrayRing::Update(const T element,const int index=0)
{
//--- check the index correctness:
if((index/m_size)==0)
{
//--- update
m_data[(m_size+m_last_pos-index)%m_size]=element;
//--- successful
return(true);
}
//--- if the index is wrong:
return(false);
}