OLP. Problemas de aplicación - página 13

 
TheXpert:
Muéstrame un ejemplo para que no haya confusión, luego te responderé.

//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("Пользовательское значение");
  }

Un ejemplo es sencillo. Supongamos que se gastan 15 "ciclos de ordenador" en la inicialización automática del miembro a1.strA. He llegado a la conclusión preliminar de que también se gastan 15 ciclos en la inicialización del miembro b1.strB. ¿Es correcto?

 

En la clase CExpert de la biblioteca estándar, existen estas declaraciones protegidas

//--- 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

Al mismo tiempo, el constructor de este objeto contiene las siguientes cadenas

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

Intenté crear algo similar en mi clase, pero sin ninguna otra inicialización (como Init e InitXXX).

El compilador compiló todo sin advertencias ni errores, pero cuando traté de instalar el EA en el gráfico, obtuvo un error crítico 281 (acceso al puntero no válido) y el EA fue eliminado del gráfico.

A este respecto, tengo algunas preguntas:

1. ¿Qué debo hacer en el constructor (especificar NULL o especificar el puntero al objeto específico)?

2. ¿Es obligatoria la inicialización del puntero del tipo InitTrade?

 
Interesting:

En la clase CExpert de la biblioteca estándar, existen estas declaraciones protegidas

Al mismo tiempo, el constructor de este objeto contiene las siguientes cadenas

Intenté crear algo similar en mi clase, pero sin ninguna otra inicialización (como Init e InitXXX).

El compilador compiló todo sin advertencias ni errores, pero cuando traté de instalar el EA en el gráfico, obtuvo un error crítico 281 (acceso al puntero no válido) y el EA fue eliminado del gráfico.

A este respecto, tengo algunas preguntas:

1. ¿Qué debo hacer en el constructor (especificar NULL o especificar el puntero al objeto específico)?

2. ¿Es obligatoria la inicialización del puntero del tipo InitTrade?

1. Ambos son correctos. Todo depende de la implementación particular de la clase (no específicamente de CExpert). Sin embargo, es mejor crear objetos dinámicos en el método InitXXX, que devuelve bool (porque el constructor no devuelve el resultado de la ejecución y tendrás que restablecer la bandera de inicialización y luego analizarla (la bandera).

2. Por supuesto que sí. En caso contrario, se producirá el error crítico 281 (acceso al puntero no válido).

PS. Por cierto, gracias. Tendré que insertar comprobaciones de punteros antes de su uso.

 
Yedelkin:

Un ejemplo es sencillo. Supongamos que se gastan 15 "ciclos de ordenador" en la inicialización automática del miembro a1.strA. He llegado a la conclusión preliminar de que también se gastan 15 ciclos en la inicialización del miembro b1.strB. ¿Es esto correcto?

No, no es el tacto en absoluto. O tal vez no se trate realmente del reloj.
 
TheXpert:
No, no se trata del reloj en absoluto. Bueno, o no realmente sobre el reloj.

Bien, entonces una pregunta muy sencilla: ¿qué es más rápido de inicializar en el tiempo, el miembro a1.strA o el miembro b1.strB del ejemplo anterior?

¿O qué leer "punto por punto"? Físicamente no hay forma de aprender a programar a nivel de "procesador de máquina".

 
Yedelkin:

Bien, entonces una pregunta muy sencilla: ¿qué es más rápido de inicializar en el tiempo, el miembro a1.strA o el miembro b1.strB del ejemplo anterior?

¿O qué leer "punto por punto"? Físicamente no hay forma de aprender a programar a nivel de "procesador de máquina".

a1.strA se inicializará más rápido porque su proceso de inicialización es simplemente la puesta a cero en el lugar. Para b1.strB se hará una asignación de memoria.

Sin embargo, esta diferencia es bastante difícil de medir, ya que es mucho menos del uno por ciento, teniendo en cuenta el código en torno a la inicialización

 
Yedelkin:

que se inicializa más rápido

la pregunta es incorrecta.
 
stringo:

Para b1.strB se hará una asignación de memoria.

Aquí tienes, gracias - el eslabón que faltaba en mi lógica.

TheXpert, gracias por la ayuda. Traté de explicar el punto con mis propias palabras. Estoy de acuerdo en que una pregunta verdaderamente correcta es la que hacen los que saben. Pero no suelen hacer preguntas de mi nivel :)

 
uncleVic:

1. Es correcto en ambos sentidos. Todo depende de la implementación específica de la clase (no específicamente de CExpert). Sin embargo, es mejor crear objetos dinámicos en el método InitXXX, que devuelve bool (porque el constructor no devuelve el resultado de la ejecución y tendremos que restablecer/desestablecer la bandera de inicialización y luego analizarla (la bandera).

2. Por supuesto que sí. En caso contrario, error crítico 281 (acceso al puntero no válido).

PS. Por cierto, gracias. Tendré que insertar comprobaciones de punteros antes de su uso.

Gracias, ahora todo está en su sitio. Sin embargo, hay una pregunta más. Supongamos que se produce el error 281, pero es mejor que el Asesor Experto no se descargue. ¿Qué debo hacer?

Permítanme aclarar mi pregunta - ¿Qué hacer si 281 error se produce después de todos los pasos de la inicialización, pero no afectaría el trabajo principal de Asesor de Expertos lo suficientemente crítico como para no ejecutarlo en absoluto?

 
Interesting:

Supongamos que se produce el error 281, pero es deseable que el EA no se descargue. ¿Qué debemos hacer entonces?

Permítanme aclarar mi pregunta: ¿Qué hacer si el error 281 se produce después de todos los pasos de la inicialización, pero no afectará el trabajo principal del Asesor Experto lo suficientemente crítico como para no ejecutarlo en absoluto?

"Acceso a puntero no válido" =="Intento de acceso a un puntero no válido"? Si es así, entonces

Un intento de acceder a un puntero no válido provoca un fallo del programa. Por eso es necesario utilizar la función CheckPointer() antes de utilizar un puntero. Un puntero puede ser inválido en los siguientes casos

  • el puntero es NULL;
  • si el objeto ha sido destruido por el operador delete
  • .