Obrigado pela resposta, você não é nada mau) Agora tudo faz sentido) UPD Esta construção também funciona
Preste atenção ao que o método At() devolve. Se devolver o NULL, irá cair em erro crítico. Antes de aceder a um ponteiro para um objecto, verifique se não é NULL
Já notado) Portanto, a solução é declarar globalmente objectos vazios.... E se não souber de antemão quantos deles haverá? Basta declarar "com reserva" ? :) P.S. Não encontrei esta forma de declarar objectos na ajuda integrada
Era uma vez Artyom escreveu-me esta aula. Não consigo explicar em detalhes como funciona. Mas Artem lembrar-se-á e será capaz de explicar. Aqui está a classe em si
#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;
}
E aqui está o ciclo de criação de apontadores no 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());
}
}
e em 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) é o tamanho do conjunto de estruturas em que os caracteres com os quais trabalhar são listados.
Artyom escreveu-me uma vez esta aula. Não consigo explicar em detalhe como funciona. Mas Artyom lembrar-se-á e será capaz de explicar. Aqui está a classe em si
E aqui está o ciclo de criação de apontadores no OnInit()
e em OnTimer()
ArraySize(Rates) é o tamanho do conjunto de estruturas onde estão listados os caracteres com os quais se deve trabalhar.
Aqui:
for(int i = 0; i < ArraySize(Rates); i++)
Eu faria antes do total - simplesmente pela razão de estar a ler caracteres da tabela de Tarifas (certo?), criando instâncias da nova classe de barras e adicionando-as à lista.
Em qualquer erro de adição, o tamanho da lista de apontadores para instâncias da nova classe de barras não corresponderá ao tamanho da matriz de Tarifas.
Em geral, deve ser algo parecido com isto:
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())
{// и дальше………
E é aqui que também precisa de verificar se a lista foi acrescentada com sucesso:
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());
}
}
Eu faria antes do total - simplesmente pela razão de que lê caracteres da matriz de Tarifas (certo?), criar instâncias da nova classe de barras e adicioná-las à lista.
Em qualquer erro de adição, o tamanho da lista de apontadores para instâncias da nova classe de barras não corresponderá ao tamanho da matriz de Tarifas.
Em geral, deve ser algo parecido com isto:
E é aqui que também precisa de verificar se a lista foi acrescentada com sucesso:
algo parecido com isto:
para evitar fugas de memória quando um ponteiro para um novo objecto é adicionado à lista por engano
Obrigado. Já o tenho, vou corrigi-lo desta forma:))))
Detesto continuar; operador e tente não o utilizar. Exclusivamente em casos desesperados.
if(nb==NULL)
continue;
como difere de
if(nb!=NULL)
{
}
Outra coisa é se por erro o ponteiro falhado for apagado... Mas mesmo aqui podemos fazer sem odiar continuar; simplesmente apagando Print(). Foi necessário durante a depuração e a tentativa de compreender o que se está a passar, e se durante o trabalho acontecer algum erro, não vou entender o que está errado de qualquer maneira... É mais fácil reinstalar o SO do que compreender os registos.
Já que estamos a falar do assunto, diga-nos, sem entrar em detalhes, qual é a diferença entre um ponteiro e uma variável de classe, e qual é preferível. Posso ler sobre isso na Internet em detalhes que são difíceis de compreender. Um entendimento superficial é suficiente para mim, por assim dizer.
Preste atenção ao que o método At() retorna. Se devolver o NULL, irá cair em erro crítico. Antes de aceder a um ponteiro para um objecto, verificar que não é NULL.
Artyom escreveu-me uma vez esta aula. Não consigo explicar em detalhe como funciona. Mas Artyom lembrar-se-á e será capaz de explicar. De qualquer forma, aqui está a própria turma
//+------------------------------------------------------------------+//| 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, obrigado por uma resposta tão detalhada. O objectivo da variável ret no fragmento de código citado não é claro... Para que é calculado, se em qualquer caso o método retorna matriz[0] ? P.S. E porquê utilizá-lo num método de classe? Estamos a trabalhar com membros desta classe em particular...
Obrigado. Já percebi, vou arranjá-lo assim... :)))
Odeio o operador contínuo; e tento não o utilizar. Exclusivamente em casos desesperados.
como difere de
Outra coisa é se, quando ocorre um erro, se apagar o ponteiro falhado... Mas também aqui se pode fazer sem odiar continuar; basta apagar Print(). Foi necessário durante a depuração e a tentativa de compreender o que se está a passar, e se durante o trabalho acontecer algum erro, eu não vou entender o que está errado de qualquer maneira... Prefiro reinstalar o SO do que compreender os registos.
Já que estamos a falar do assunto, diga-nos, sem entrar em detalhes, qual é a diferença entre um ponteiro e uma variável de classe, e qual é preferível. Posso ler sobre isso na Internet em detalhes que são difíceis de compreender. Um entendimento superficial é suficiente para mim, por assim dizer.
Estou a tentar livrar-me de parênteses desnecessários - para não fazer florestas e ramos. Sem a impressão não há necessidade de parênteses - basta apagar o objecto.
Com o novo operador cria-se um mecanismo que se encontra fisicamente "algures". O novo operador devolve o endereço deste "algures". E esta é a única forma de se referir a este "mecanismo".
E o parafuso dentro desse mecanismo é uma variável.
Alexey, obrigado por uma resposta tão detalhada. A finalidade da variável ret no fragmento de código dado não é clara... Porque é que é calculado se o método retorna matriz[0] de qualquer maneira?
Alexey reelaborou algo no código que eu dei. Ou talvez também o tenha perdido - escrevi-o "de joelhos" como um simples exemplo para explicar aquilo de que já não me lembro.
Obrigado pela resposta, você não é nada mau)
Agora tudo faz sentido)
UPD
Esta construção também funciona
Preste atenção ao que o método At() devolve. Se devolver o NULL, irá cair em erro crítico. Antes de aceder a um ponteiro para um objecto, verifique se não é NULL
Já notado)
Portanto, a solução é declarar globalmente objectos vazios....
E se não souber de antemão quantos deles haverá? Basta declarar "com reserva" ? :)
P.S. Não encontrei esta forma de declarar objectos na ajuda integrada
Era uma vez Artyom escreveu-me esta aula. Não consigo explicar em detalhes como funciona. Mas Artem lembrar-se-á e será capaz de explicar. Aqui está a classe em si
E aqui está o ciclo de criação de apontadores no OnInit()
e em OnTimer()
ArraySize(Rates) é o tamanho do conjunto de estruturas em que os caracteres com os quais trabalhar são listados.
Artyom escreveu-me uma vez esta aula. Não consigo explicar em detalhe como funciona. Mas Artyom lembrar-se-á e será capaz de explicar. Aqui está a classe em si
E aqui está o ciclo de criação de apontadores no OnInit()
e em OnTimer()
ArraySize(Rates) é o tamanho do conjunto de estruturas onde estão listados os caracteres com os quais se deve trabalhar.
Aqui:
Eu faria antes do total - simplesmente pela razão de estar a ler caracteres da tabela de Tarifas (certo?), criando instâncias da nova classe de barras e adicionando-as à lista.
Em qualquer erro de adição, o tamanho da lista de apontadores para instâncias da nova classe de barras não corresponderá ao tamanho da matriz de Tarifas.
Em geral, deve ser algo parecido com isto:
E é aqui que também precisa de verificar se a lista foi acrescentada com sucesso:
algo parecido com isto:
para evitar fugas de memória quando um ponteiro para um novo objecto é adicionado à lista por enganoAqui:
Eu faria antes do total - simplesmente pela razão de que lê caracteres da matriz de Tarifas (certo?), criar instâncias da nova classe de barras e adicioná-las à lista.
Em qualquer erro de adição, o tamanho da lista de apontadores para instâncias da nova classe de barras não corresponderá ao tamanho da matriz de Tarifas.
Em geral, deve ser algo parecido com isto:
E é aqui que também precisa de verificar se a lista foi acrescentada com sucesso:
algo parecido com isto:
para evitar fugas de memória quando um ponteiro para um novo objecto é adicionado à lista por enganoObrigado. Já o tenho, vou corrigi-lo desta forma:))))
Detesto continuar; operador e tente não o utilizar. Exclusivamente em casos desesperados.
como difere de
Outra coisa é se por erro o ponteiro falhado for apagado... Mas mesmo aqui podemos fazer sem odiar continuar; simplesmente apagando Print(). Foi necessário durante a depuração e a tentativa de compreender o que se está a passar, e se durante o trabalho acontecer algum erro, não vou entender o que está errado de qualquer maneira... É mais fácil reinstalar o SO do que compreender os registos.Já que estamos a falar do assunto, diga-nos, sem entrar em detalhes, qual é a diferença entre um ponteiro e uma variável de classe, e qual é preferível. Posso ler sobre isso na Internet em detalhes que são difíceis de compreender. Um entendimento superficial é suficiente para mim, por assim dizer.
Preste atenção ao que o método At() retorna. Se devolver o NULL, irá cair em erro crítico. Antes de aceder a um ponteiro para um objecto, verificar que não é NULL.
Artem, obrigado pelo valioso comentário)
Obrigado. Já percebi, vou arranjá-lo assim... :)))
Odeio o operador contínuo; e tento não o utilizar. Exclusivamente em casos desesperados.
Como difere de
A iteração do loop não terminará e não iniciará uma nova, mas avançará para a próxima iteração. A lógica irá mudar.
Artyom escreveu-me uma vez esta aula. Não consigo explicar em detalhe como funciona. Mas Artyom lembrar-se-á e será capaz de explicar. De qualquer forma, aqui está a própria turma
Alexey, obrigado por uma resposta tão detalhada.
O objectivo da variável ret no fragmento de código citado não é claro...
Para que é calculado, se em qualquer caso o método retorna matriz[0] ?
P.S.
E porquê utilizá-lo num método de classe? Estamos a trabalhar com membros desta classe em particular...
Obrigado. Já percebi, vou arranjá-lo assim... :)))
Odeio o operador contínuo; e tento não o utilizar. Exclusivamente em casos desesperados.
como difere de
Outra coisa é se, quando ocorre um erro, se apagar o ponteiro falhado... Mas também aqui se pode fazer sem odiar continuar; basta apagar Print(). Foi necessário durante a depuração e a tentativa de compreender o que se está a passar, e se durante o trabalho acontecer algum erro, eu não vou entender o que está errado de qualquer maneira... Prefiro reinstalar o SO do que compreender os registos.Já que estamos a falar do assunto, diga-nos, sem entrar em detalhes, qual é a diferença entre um ponteiro e uma variável de classe, e qual é preferível. Posso ler sobre isso na Internet em detalhes que são difíceis de compreender. Um entendimento superficial é suficiente para mim, por assim dizer.
A iteração do ciclo não terminará e não iniciará um novo ciclo, mas passará para o próximo Se. A lógica irá mudar.
Alexey, obrigado por uma resposta tão detalhada.
A finalidade da variável ret no fragmento de código dado não é clara...
Porque é que é calculado se o método retorna matriz[0] de qualquer maneira?