OOP, modelli e macro in mql5, sottigliezze e usi - pagina 26

 

È sorta una domanda:

C'è una classe "Programma" che usa le classi"Nuova barra" e "Gestore dei dati". La classe "New Bar" utilizza a sua volta la classe "Data Manager". I getter e i setter pubblici sono implementati nella classe "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;
   };

Domanda: quali sono le opzioni per l'inizializzazione del programma per la classe "New Bar" per specificare le proprietà "symbol" e "timeframe" della classe "Data Manager"? Non vorrei avere getter e setter pubblici nella classe New Bar per accedere ai campi del gestore dei dati. E vorremmo mantenere privato il gestore dei dati.

In altre parole: l'applicazione può utilizzare più classi che usano il gestore dei dati. Durante l'inizializzazione del programma, tutti i campi manager di tutte le classi devono essere inizializzati con i valori richiesti. Ma non voglio creare getter in tutte le classi per accedere ai campi del gestore dei dati. Quindi...

 
Alexey Kozitsyn:
Dalla vostra descrizione, ha senso separare queste impostazioni in un'entità separata, la stessa per tutti i manager e oltre
 
TheXpert:
Secondo la vostra descrizione ha senso separare queste impostazioni in un'entità separata, la stessa per tutti i manager e non solo

Sì, sembra che tu abbia bisogno di ereditare le classi che hanno bisogno di un gestore da una classe base che ha getter per i campi del gestore. Grazie.

 
Alexey Kozitsyn:

È sorta una domanda:

C'è una classe "Programma" che usa le classi"Nuova barra" e "Gestore dei dati". La classe "New Bar" utilizza a sua volta la classe "Data Manager". La classe "Data Manager" implementa getter e setter pubblici.

Domanda: quali sono le opzioni per l'inizializzazione del programma per la classe "New Bar" per specificare le proprietà "symbol" e "timeframe" della classe "Data Manager"? Non vorrei avere getter e setter pubblici nella classe New Bar per accedere ai campi del gestore dei dati. E vorremmo mantenere privato il gestore dei dati.

In altre parole: l'applicazione può utilizzare più classi che usano il gestore dei dati. Durante l'inizializzazione del programma, tutti i campi manager di tutte le classi devono essere inizializzati con i valori richiesti. Ma non voglio creare getter in tutte le classi per accedere ai campi del gestore dei dati. Quindi...

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){}
   };

È più o meno così che faccio io.

 
Vladimir Simakov:

Più o meno è così che faccio io.

Grazie per l'esempio, è un po' complicato finora, ma in generale l'idea è chiara. Immediatamente sorge una domanda: ok, se "un livello di annidamento" - qui è chiaro, ma se ci saranno diversi livelli di annidamento?

Aggiunto:

Non è anche chiaro perché il campo cIsDelData? Dopo tutto, potete semplicemente controllare m_data contro POINTER_DINAMIC nel distruttore. O mi sbaglio?

 

Se fate l'ereditarietà, avrete un sacco di metodi inutili. E l'oggetto deve essere privato. Quindi, non ci crederete, ma il modo più semplice è quello di impostare i setter per tutte le classi che usano il gestore dei dati.

Se tutti i gestori di dati lavorano con gli stessi parametri, è meglio non creare oggetti, ma passare un puntatore a un gestore di dati. In questo caso, è necessario solo un setter per passare il puntatore.

 
Alexey Kozitsyn:

Grazie per l'esempio, è un po' complicato finora, ma in generale l'idea è chiara. Immediatamente sorge una domanda: ok, se "un livello di annidamento" - qui è chiaro, ma se ci saranno diversi livelli di annidamento?

Aggiunto:

Non è anche chiaro perché il campo cIsDelData? Dopo tutto, potete semplicemente controllare m_data contro POINTER_DINAMIC nel distruttore. O mi sbaglio?

No, ti sbagli. Potete passare un puntatore a un oggetto dinamico e, ops, ucciderlo in modo sicuro.
E sulla nidificazione. Si crea un'istanza di un oggetto dove si ha inizialmente bisogno, e solo i puntatori ulteriormente, come nell'esempio sopra. Se in generale è destinato ad essere un singleton nel progetto, si può fare un singleton, ma non ne ho mai fatto uno usando mql, quindi non ne ho avuto bisogno, devo provare.
 
Dmitry Fedoseev:
Vladimir Simakov:

Grazie, ci penserò.

 
Vladimir Simakov:

Lo faccio più o meno così.

cosa significa questa lineaCDataManager* m_data;

Ragazzi, voglio fare una cosa del genere. Ho 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 это дополнительное выражение которое будет дописываться в новый макрос

Come risultato avrò 2 macrofoor efoor1.

 
Seric29:

cosa significa questa lineaCDataManager* m_data;

Ragazzi, voglio fare una cosa del genere. Ho una macro.

Come risultato avrò 2 macrofoor efoor1.

Un puntatore a un oggetto.

Senza offesa, ma è troppo presto per te per occuparti di tali macro. Prima di tutto, capite perché l'ho fatto:

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