OOP, plantillas y macros en mql5, sutilezas y usos - página 26

 

Ha surgido una pregunta:

Hay una clase "Programa" que utiliza las clases"Nueva barra" y "Gestor de datos". A su vez, la clase "Nueva barra" también utiliza la clase "Gestor de datos". Los getters y setters públicos se implementan en la clase "Data Manager".

class CDataManager
   {
private:
    string          m_symbol;
    ENUM_TIMEFRAMES m_timeframe;
public:
    //--- Геттеры и сеттеры
   };
class CNewBar
   {
private:
    CDataManager  m_data;
   };
class СProgram
   {
private:
    CNewBar        m_newBar;
    CDataManager   m_data;
   };

Pregunta: ¿Cuáles son las opciones para la inicialización del programa de la clase "Nueva barra" para especificar las propiedades "símbolo" y "marco temporal" de la clase "Gestor de datos"? No me gustaría tener getters y setters públicos en la clase New Bar para acceder a los campos del gestor de datos. Y nos gustaría mantener la privacidad del gestor de datos.

En otras palabras: La aplicación puede utilizar varias clases que utilizan el gestor de datos. Durante la inicialización del programa, todos los campos del gestor de todas las clases deben ser inicializados con los valores requeridos. Pero no quiero crear getters en todas las clases para acceder a los campos del gestor de datos. Así que...

 
Alexey Kozitsyn:
Por su descripción, tiene sentido separar estos ajustes en una entidad separada, la misma para todos los gerentes y más allá
 
TheXpert:
Según su descripción tiene sentido separar estos ajustes en una entidad separada, la misma para todos los gestores y no sólo

Sí, parece que necesitas heredar las clases que necesitan un gestor de una clase base que tenga getters a los campos del gestor. Gracias.

 
Alexey Kozitsyn:

Ha surgido una pregunta:

Hay una clase "Programa" que utiliza las clases"Nueva barra" y "Gestor de datos". A su vez, la clase "Nueva barra" también utiliza la clase "Gestor de datos". Los getters y setters públicos se implementan en la clase "Data Manager".

Pregunta: ¿Cuáles son las opciones para la inicialización del programa de la clase "Nueva barra" para especificar las propiedades "símbolo" y "marco temporal" de la clase "Gestor de datos"? No me gustaría tener getters y setters públicos en la clase New Bar para acceder a los campos del gestor de datos. Y nos gustaría mantener la privacidad del gestor de datos.

En otras palabras: La aplicación puede utilizar varias clases que utilizan el gestor de datos. Durante la inicialización del programa, todos los campos del gestor de todas las clases deben ser inicializados con los valores requeridos. Pero no quiero crear getters en todas las clases para acceder a los campos del gestor de datos. Así que...

class CDataManager
   {
private:
    string          m_symbol;
    ENUM_TIMEFRAMES m_timeframe;
public:
    CDataManager():m_symbol(_Symbol),m_timeframe(_Period){}
    CDataManager(string symbol,ENUM_TIMEFRAMES frame):m_symbol(symbol),m_timeframe(frame){}
    //--- Геттеры и сеттеры
   };
class CNewBar
   {
private:
    CDataManager*  m_data;
    bool           cIsDelData;
public:
   CNewBar(CDataManager* data=NULL):m_data(!data?new CDataManager:data),cIsDelData(!data){}
   CNewBar(string symbol,ENUM_TIMEFRAMES frame):m_data(new CDataManager(symbol,frame)),cIsDelData(true){}
  ~CNewBar() {if (cIsDelData) delete m_data;}
   };
class CProgram
   {
private:
    CNewBar        m_newBar;
    CDataManager   m_data;
public:
    CProgram():m_newBar(&m_data){}
   };

Así es como lo hago yo.

 
Vladimir Simakov:

Así es más o menos como lo hago yo.

Gracias por el ejemplo, hasta ahora es un poco complicado, pero en general la idea es clara. Inmediatamente surge una pregunta: vale, si "un nivel de anidación" - aquí está claro, pero ¿si habrá varios niveles de anidación?

Añadido:

Tampoco está claro por qué el campo cIsDelData? Después de todo, puedes comprobar m_data contra POINTER_DINAMIC en el destructor. ¿O me equivoco?

 

Si se hace la herencia, se obtendrá un montón de métodos innecesarios. Y el objeto debe ser privado. Así que, no te lo vas a creer, pero la forma más fácil es hacer setters para todas las clases que utilizan el gestor de datos.

Si todos los gestores de datos trabajan con los mismos parámetros, es mejor no crear objetos, sino pasar un puntero a un gestor de datos. En este caso, sólo se necesita un setter para pasar el puntero.

 
Alexey Kozitsyn:

Gracias por el ejemplo, hasta ahora es un poco complicado, pero en general la idea es clara. Inmediatamente surge una pregunta: vale, si "un nivel de anidación" - aquí está claro, pero ¿si habrá varios niveles de anidación?

Añadido:

Tampoco está claro por qué el campo cIsDelData? Después de todo, puedes comprobar m_data contra POINTER_DINAMIC en el destructor. ¿O me equivoco?

No, te equivocas. Se puede pasar un puntero a un objeto dinámico y, oops, matarlo de forma segura.
Y sobre la anidación. Se crea una instancia de un objeto donde se necesita inicialmente, y sólo los punteros más, como en el ejemplo anterior. Si en general se pretende que sea un singleton en el proyecto, se puede hacer un singleton, pero nunca he hecho uno usando mql, así que no lo he necesitado, tengo que probarlo.
 
Dmitry Fedoseev:
Vladimir Simakov:

Gracias, lo pensaré.

 
Vladimir Simakov:

Lo hago más o menos así.

lo que significa esta líneaCDataManager* m_data;

Chicos quiero hacer una cosa así. Tengo una macro.

#define  foor(a,b,v) \
for(;Funkziya(a,b,v);b++)
//я хочу доработать макрос чтобы получилось так
#define  foor1(a,b,v,g) \
//за основу будет взят первый макрос
for(;Funkziya(a,b,v)&&g;b++)//эффект должен быть такой где g это дополнительное выражение которое будет дописываться в новый макрос

Como resultado tendré 2 macrosfoor yfoor1.

 
Seric29:

lo que significa esta líneaCDataManager* m_data;

Chicos quiero hacer una cosa así. Tengo una macro.

Como resultado tendré 2 macrosfoor yfoor1.

Un puntero a un objeto.

No te ofendas, pero es demasiado pronto para que te ocupes de esas macros. En primer lugar, entiendan por qué he hecho esto:

#define  foor1(a,b,v,g) \
for(;Funkziya(a,b,v)&&(g);(b)++)