OLP. Questões de aplicação - página 13

 
TheXpert:
Mostre-me um exemplo para que não haja confusão, então eu responderei.

//1-ый вариант. Переменная-член strA инициализируется автоматически
class A
  {
public:
   string            strA;
                     A(void) { Print("strA=",strA); };
                    ~A(void){};
  };
//2-ой вариант. Переменная-член strB инициализируется при помощи инициализатора пользовательским значением
class B
  {
public:
   string            strB;
                     B(const string str) : strB(str) { Print("strB=",strB); }
                    ~B(void){};
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   A a1;
   B b1("Пользовательское значение");
  }

Um exemplo é simples. Suponha que são gastos 15 "ciclos informáticos" na inicialização automática do membro a1.strA. Cheguei a uma conclusão preliminar de que também são gastos 15 ciclos na inicialização do membro b1.strB. É correcto?

 

Na classe CExpert da biblioteca padrão, existem estas declarações guardadas

//--- trading objects
CExpertTrade     *m_trade;    // trading object
CExpertSignal    *m_signal;   // trading signals object
CExpertMoney     *m_money;    // money manager object
CExpertTrailing  *m_trailing; // trailing stops object

Ao mesmo tempo, o construtor deste objecto contém as seguintes cordas

m_trade    =NULL;
m_signal   =NULL;
m_money    =NULL;
m_trailing =NULL;

Tentei criar algo semelhante na minha turma, mas sem qualquer outra inicialização (como Init e InitXXX).

O compilador compilou tudo sem quaisquer avisos ou erros, mas quando tentei instalar a EA no gráfico, obtive um erro crítico 281 (Invalid pointer access) e a EA foi apagada do gráfico.

A este respeito, tenho algumas perguntas a fazer:

1. O que devo fazer no construtor (especificar NULL ou especificar o ponteiro para o objecto específico)?

2. A inicialização do ponteiro do tipo InitTrade é obrigatória?

 
Interesting:

Na classe CExpert da biblioteca padrão, existem estas declarações guardadas

Ao mesmo tempo, o construtor deste objecto contém as seguintes cordas

Tentei criar algo semelhante na minha turma, mas sem qualquer outra inicialização (como Init e InitXXX).

O compilador compilou tudo sem quaisquer avisos ou erros, mas quando tentei instalar a EA no gráfico, obtive um erro crítico 281 (Invalid pointer access) e a EA foi apagada do gráfico.

A este respeito, tenho algumas perguntas a fazer:

1. O que devo fazer no construtor (especificar NULL ou especificar o ponteiro para o objecto específico)?

2. A inicialização do ponteiro do tipo InitTrade é obrigatória?

1. Ambos estão correctos. Tudo depende da implementação particular da classe (não especificamente do CExpert). Contudo, é melhor criar objectos dinâmicos no método InitXXX, que retorna bool (porque o construtor não retorna o resultado da execução e terá de repor a bandeira de inicialização e depois analisá-la (a bandeira).

2. É claro que sim. Caso contrário, ocorrerá o erro crítico 281 (acesso ao ponteiro inválido).

PS. A propósito, obrigado. Terei de inserir verificações de ponteiro antes de usar.

 
Yedelkin:

Um exemplo é simples. Suponha que são gastos 15 "ciclos informáticos" na inicialização automática do membro a1.strA. Cheguei a uma conclusão preliminar de que também são gastos 15 ciclos na inicialização do membro b1.strB. Será isto correcto?

Não, não são de todo os factos. Ou talvez não seja realmente sobre o relógio.
 
TheXpert:
Não, não tem nada a ver com o relógio. Bem, ou não realmente sobre o relógio.

OK, então uma pergunta muito simples: o que é mais rápido de iniciar a tempo, membro a1.strA ou membro b1.strB do exemplo acima?

Ou o que ler "ponto por ponto"? Não há forma física de aprender programação a um nível de "máquina-processador".

 
Yedelkin:

OK, então uma pergunta muito simples: o que é mais rápido de iniciar a tempo, membro a1.strA ou membro b1.strB do exemplo acima?

Ou o que ler "ponto por ponto"? Não há forma física de aprender programação de nível "máquina-processador".

a1.strA inicializar-se-á mais rapidamente porque o seu processo de inicialização está simplesmente a zerar no lugar. Para b1.strB será feita uma alocação de memória.

No entanto, esta diferença é bastante difícil de medir, pois é muito inferior a um por cento, tendo em conta o código em torno da inicialização

 
Yedelkin:

que se inicia mais rapidamente

a questão é incorrecta.
 
stringo:

Para b1.strB será feita uma alocação de memória.

Aqui tem, obrigado - o elo que falta na minha lógica.

TheXpert, obrigado pela ajuda. Tentei explicar o ponto nas minhas próprias palavras. Concordo que uma pergunta verdadeiramente correcta é feita por aqueles que estão a par da situação. Mas normalmente não fazem as minhas perguntas de nível :)

 
uncleVic:

1. É correcto em ambos os sentidos. Tudo depende da implementação específica da classe (não especificamente do CExpert). Contudo, é melhor criar objectos dinâmicos no método InitXXX, que devolve bool (porque o construtor não devolve o resultado da execução e teremos de reiniciar/anular a bandeira de inicialização e depois analisá-la (a bandeira).

2. É claro que sim. Caso contrário, erro crítico 281 (acesso inválido ao ponteiro).

PS. A propósito, obrigado. Terei de inserir verificações de ponteiro antes de usar.

Obrigado, agora tudo está no seu lugar. No entanto, há mais uma questão. Vamos supor que o erro 281 ocorre, mas é melhor que o Expert Advisor não seja descarregado. O que devo fazer?

Deixe-me esclarecer a minha pergunta - O que fazer se 281 erros ocorrerem após todas as etapas da inicialização, mas não afectariam o trabalho principal do Expert Advisor de forma suficientemente crítica para não o executar de todo?

 
Interesting:

Suponhamos que ocorre um erro 281, mas é desejável que a EA não seja descarregada. O que devemos então fazer?

Deixe-me esclarecer a minha pergunta: O que fazer se o erro 281 ocorrer após todas as etapas de inicialização, mas não afectará o trabalho principal do Consultor Especialista de forma suficientemente crítica para não o executar de todo?

"Invalid pointer access" =="Tentativa de acesso a um ponteiro inválido"? Se sim, então

Uma tentativa de acesso a um ponteiro inválido causa uma falha de programa. É por isso que há necessidade de usar a função CheckPointer() antes de usar um ponteiro. Um ponteiro pode ser inválido nos seguintes casos

  • o ponteiro é NULL;
  • se o objecto tiver sido destruído pelo operador de eliminação
  • .
Razão: