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

[Eliminato]  

È 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
[Eliminato]  
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.

[Eliminato]  
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.
[Eliminato]  
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)++)