Thanks for the reply, you're not evil at all) Now it all makes sense) UPD This construction works too
Pay attention to what At() method returns. If it returns NULL, you will crash on critical error. Before accessing a pointer to an object, check it is not NULL
Already noticed) So the solution is to declare globally empty objects.... And if you don't know beforehand how many of them there will be ? Just declare "with reserve" ? :) P.S. I didn't find this way of declaring objects in the built-in help
Once upon a time Artyom wrote me this class. I can't explain in details how it works. But Artem will remember and will be able to explain. Here is the class itself
#include <Arrays\ArrayObj.mqh>
/********************************************************************\
| Класс Новый бар |
\********************************************************************/class CNewBar : public CObject
{
private:
string m_symbol;
ENUM_TIMEFRAMES m_timeframe;
datetime m_time;
datetime Time(void); // Возвращает время нулевого бараstringSymbol(void) { returnthis.m_symbol; }
public:
ENUM_TIMEFRAMES Timeframe(void) { returnthis.m_timeframe; }
datetime GetTime(void) { returnthis.m_time; } // Возвращает время последнего обращенияbool IsNewBar(void); // Основная функция класса
CNewBar(conststring symbol,constENUM_TIMEFRAMES timeframe);
~CNewBar(void){;}
};
//+------------------------------------------------------------------+//| Конструктор |//+------------------------------------------------------------------+
CNewBar::CNewBar(conststring symbol,constENUM_TIMEFRAMES timeframe) : m_time(0)
{
this.m_symbol = symbol;
this.m_timeframe = (timeframe == PERIOD_CURRENT ? Period() : timeframe);
}
//+------------------------------------------------------------------+//| CNewBar Time Возвращает время нулевого бара |//+------------------------------------------------------------------+datetime CNewBar::Time(void)
{
datetime array[1], ret;
ret = CopyTime(this.m_symbol, this.m_timeframe, 0, 1, array) == 1 ? array[0] : 0;
return(array[0]);
}
//+------------------------------------------------------------------+//| CNewBar IsNewBar Основная функция класса |//+------------------------------------------------------------------+bool CNewBar::IsNewBar(void)
{
datetime tm = this.Time();
if(tm == 0)
returnfalse;
if(tm != this.m_time)
{
this.m_time = tm;
returntrue;
}
returnfalse;
}
And here is the loop of creating pointers in OnInit()
for(int i = 0; i < ArraySize(Rates); i++)
{
CNewBar* nb = new CNewBar(Rates[i].m_Symbols, timefram);
if(nb != NULL)
{
list_new_bar.Add(nb);
Print(nb.IsNewBar(), " ***** ", Rates[i].m_Symbols, " ***** ", nb.Time());
}
}
and in OnTimer()
voidOnTimer()
{
int total = list_new_bar.Total();
for(int i = 0; i < ArraySize(Rates); i++)
{
CNewBar* nb = list_new_bar.At(i);
if(nb == NULL)
continue;
bool new_bar = nb.IsNewBar();
if(new_bar)
{// и дальше………
ArraySize(Rates) is the size of array of structures in which the characters to work with are listed.
Artyom once wrote me this class. I can't explain in detail how it works. But Artyom will remember and will be able to explain. Well, here is the class itself
And here is the loop of creating pointers in OnInit()
and in OnTimer()
ArraySize(Rates) is the size of array of structures in which the characters to work with are listed.
Here:
for(int i = 0; i < ArraySize(Rates); i++)
I would do before total - simply for the reason that you're reading characters from the Rates array (right?), creating instances of the new bar class and adding them to the list.
On any addition error, the size of the list of pointers to instances of the new bar class will not match the size of the Rates array.
In general, it must be something like this:
voidOnTimer()
{
int total = list_new_bar.Total();
for(int i = 0; i < total; i++)
{
CNewBar* nb = list_new_bar.At(i);
if(nb == NULL)
continue;
if(nb.IsNewBar())
{// и дальше………
And this is where you need to check for successful addition to the list too:
for(int i = 0; i < ArraySize(Rates); i++)
{
CNewBar* nb = new CNewBar(Rates[i].m_Symbols, timefram);
if(nb != NULL)
{
list_new_bar.Add(nb);
Print(nb.IsNewBar(), " ***** ", Rates[i].m_Symbols, " ***** ", nb.Time());
}
}
I would do before total - simply for the reason that you read characters from the Rates array (right?), create instances of the new bar class and add them to the list.
On any addition error, the size of the list of pointers to instances of the new bar class will not match the size of the Rates array.
In general, it must be something like this:
And this is where you need to check for successful addition to the list too:
something like this:
to avoid memory leaks when a pointer to a new object is added to the list by mistake
Thanks. I got it, I'll correct it to this way:)))
I hate continue; operator and try not to use it. Exclusively in hopeless cases.
if(nb==NULL)
continue;
how it differs from
if(nb!=NULL)
{
}
Another thing is if at error the failed pointer is deleted... But even here we can do without hated continue; simply by deleting Print(). It was needed during debugging and trying to understand what's going on, and if during work some error happens, I won't understand what's wrong anyway... It's easier to reinstall OS than to understand logs.
Since we're on the subject, please tell me, without getting into details, what is the difference between a pointer and a class variable, and which is preferable. I can read about it on the Internet in details that are difficult to understand. A superficial understanding is enough for me, so to speak...
Pay attention to what the At() method returns. If it returns NULL, you will crash on critical error. Before accessing a pointer to an object, check it is not NULL.
Artyom once wrote me this class. I can't explain in detail how it works. But Artyom will remember and will be able to explain. Anyway, here is the class itself
//+------------------------------------------------------------------+//| CNewBar Time Возвращает время нулевого бара |//+------------------------------------------------------------------+datetime CNewBar::Time(void)
{
datetime array[1], ret;
ret = CopyTime(this.m_symbol, this.m_timeframe, 0, 1, array) == 1 ? array[0] : 0;
return(array[0]);
}
Alexey, thank you for such a detailed reply. The purpose of the ret variable in the cited code fragment is unclear... What for is it calculated, if in any case method returns array[0] ? P.S. And why use this in a class method? We are working with members of this particular class...
Another thing is if, when an error occurs, you delete the failed pointer... But even here you can do without hated continue; just delete Print(). It was needed during debugging and trying to understand what's going on, and if during work some error happens, I won't understand what's wrong anyway... I'd rather reinstall OS than understand logs.
Since we're on the subject, please tell us, without getting into details, what is the difference between a pointer and a class variable, and which is preferable. I can read about it on the Internet in details that are difficult to understand. A superficial understanding is enough for me, so to say.
I'm trying to get rid of unnecessary brackets - so I don't make forests and branches. Without the print there is no need for brackets - just delete the object.
With the new operator you create some mechanism that physically lies "somewhere". The new operator returns the address of this "somewhere". And that's the only way you can refer to this "mechanism".
Alexey, thank you for such a detailed answer. The purpose of ret variable in the given code fragment is not clear... Why is it calculated if the method returns array[0] anyway?
Alexey reworked something in the code I gave. Or maybe I missed it too - I wrote it "on my knees" as a simple example to explain what I don't remember anymore.
Allow the use of cookies to log in to the MQL5.com website.
Please enable the necessary setting in your browser, otherwise you will not be able to log in.
You are signed in. Two-factor authentication has been disabled. Set it up again and scan a new QR code, or continue with two-factor authentication disabled.
Thanks for the reply, you're not evil at all)
Now it all makes sense)
UPD
This construction works too
Pay attention to what At() method returns. If it returns NULL, you will crash on critical error. Before accessing a pointer to an object, check it is not NULL
Already noticed)
So the solution is to declare globally empty objects....
And if you don't know beforehand how many of them there will be ? Just declare "with reserve" ? :)
P.S. I didn't find this way of declaring objects in the built-in help
Once upon a time Artyom wrote me this class. I can't explain in details how it works. But Artem will remember and will be able to explain. Here is the class itself
And here is the loop of creating pointers in OnInit()
and in OnTimer()
ArraySize(Rates) is the size of array of structures in which the characters to work with are listed.
Artyom once wrote me this class. I can't explain in detail how it works. But Artyom will remember and will be able to explain. Well, here is the class itself
And here is the loop of creating pointers in OnInit()
and in OnTimer()
ArraySize(Rates) is the size of array of structures in which the characters to work with are listed.
Here:
I would do before total - simply for the reason that you're reading characters from the Rates array (right?), creating instances of the new bar class and adding them to the list.
On any addition error, the size of the list of pointers to instances of the new bar class will not match the size of the Rates array.
In general, it must be something like this:
And this is where you need to check for successful addition to the list too:
something like this:
to avoid memory leaks when a pointer to a new object is added to the list by mistakeHere:
I would do before total - simply for the reason that you read characters from the Rates array (right?), create instances of the new bar class and add them to the list.
On any addition error, the size of the list of pointers to instances of the new bar class will not match the size of the Rates array.
In general, it must be something like this:
And this is where you need to check for successful addition to the list too:
something like this:
to avoid memory leaks when a pointer to a new object is added to the list by mistakeThanks. I got it, I'll correct it to this way:)))
I hate continue; operator and try not to use it. Exclusively in hopeless cases.
how it differs from
Another thing is if at error the failed pointer is deleted... But even here we can do without hated continue; simply by deleting Print(). It was needed during debugging and trying to understand what's going on, and if during work some error happens, I won't understand what's wrong anyway... It's easier to reinstall OS than to understand logs.Since we're on the subject, please tell me, without getting into details, what is the difference between a pointer and a class variable, and which is preferable. I can read about it on the Internet in details that are difficult to understand. A superficial understanding is enough for me, so to speak...
Pay attention to what the At() method returns. If it returns NULL, you will crash on critical error. Before accessing a pointer to an object, check it is not NULL.
Artem, thanks for the valuable comment)
Thank you. I get it, I'll fix it like this... :)))
I hate the continue operator; and try not to use it. Exclusively in hopeless cases.
How it differs from
The loop iteration won't end and it won't start a new one, but it will move on to the next iteration. The logic will change.
Artyom once wrote me this class. I can't explain in detail how it works. But Artyom will remember and will be able to explain. Anyway, here is the class itself
Alexey, thank you for such a detailed reply.
The purpose of the ret variable in the cited code fragment is unclear...
What for is it calculated, if in any case method returns array[0] ?
P.S.
And why use this in a class method? We are working with members of this particular class...
Thank you. I get it, I'll fix it like this... :)))
I hate the continue operator; and try not to use it. Exclusively in hopeless cases.
how it differs from
Another thing is if, when an error occurs, you delete the failed pointer... But even here you can do without hated continue; just delete Print(). It was needed during debugging and trying to understand what's going on, and if during work some error happens, I won't understand what's wrong anyway... I'd rather reinstall OS than understand logs.Since we're on the subject, please tell us, without getting into details, what is the difference between a pointer and a class variable, and which is preferable. I can read about it on the Internet in details that are difficult to understand. A superficial understanding is enough for me, so to say.
The iteration of the cycle will not end and it will not start a new one, but will move on to the next If. The logic will change.
Alexey, thank you for such a detailed answer.
The purpose of ret variable in the given code fragment is not clear...
Why is it calculated if the method returns array[0] anyway?