OOP, templates et macros dans mql5, subtilités et utilisations - page 26

 

Une question s'est posée :

Il existe une classe "Programme" qui utilise les classes"Nouvelle barre" et "Gestionnaire de données". La classe "New Bar" utilise à son tour la classe "Data Manager". Les getters et setters publics sont implémentés dans la 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;
   };

Question : Quelles sont les options pour l'initialisation du programme de la classe "New Bar" pour spécifier les propriétés "symbol" et "timeframe" de la classe "Data Manager" ? Je ne voudrais pas avoir de récupérateurs et de régleurs publics dans la classe New Bar pour accéder aux champs du gestionnaire de données. Et nous aimerions garder le gestionnaire de données privé.

En d'autres termes : l'application peut utiliser plusieurs classes qui utilisent le gestionnaire de données. Pendant l'initialisation du programme, tous les champs du gestionnaire de toutes les classes doivent être initialisés avec les valeurs requises. Mais je ne veux pas créer des getters dans toutes les classes pour accéder aux champs du gestionnaire de données. Alors...

 
Alexey Kozitsyn:
Selon votre description, il est logique de séparer ces paramètres dans une entité distincte, la même pour tous les gestionnaires et au-delà.
 
TheXpert:
Selon votre description, il est logique de séparer ces paramètres dans une entité distincte, la même pour tous les gestionnaires et non seulement

Oui, il semble que vous devez hériter des classes qui ont besoin d'un gestionnaire à partir d'une classe de base qui a des récupérateurs pour les champs du gestionnaire. Merci.

 
Alexey Kozitsyn:

Une question s'est posée :

Il existe une classe "Programme" qui utilise les classes"Nouvelle barre" et "Gestionnaire de données". La classe "New Bar" utilise à son tour la classe "Data Manager". Les getters et setters publics sont implémentés dans la classe "Data Manager".

Question : Quelles sont les options pour l'initialisation du programme de la classe "New Bar" pour spécifier les propriétés "symbol" et "timeframe" de la classe "Data Manager" ? Je ne voudrais pas avoir de récupérateurs et de régleurs publics dans la classe New Bar pour accéder aux champs du gestionnaire de données. Et nous aimerions garder le gestionnaire de données privé.

En d'autres termes : l'application peut utiliser plusieurs classes qui utilisent le gestionnaire de données. Pendant l'initialisation du programme, tous les champs du gestionnaire de toutes les classes doivent être initialisés avec les valeurs requises. Mais je ne veux pas créer des getters dans toutes les classes pour accéder aux champs du gestionnaire de données. Alors...

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

C'est à peu près comme ça que je fais.

 
Vladimir Simakov:

C'est à peu près comme ça que je fais.

Merci pour l'exemple, c'est un peu compliqué jusqu'à présent, mais en général l'idée est claire. Une question se pose immédiatement : ok, si "un niveau d'imbrication" - ici c'est clair, mais s'il y aura plusieurs niveaux d'imbrication ?

Ajouté :

On ne sait pas non plus pourquoi le champ cIsDelData ? Après tout, vous pouvez simplement vérifier m_data par rapport à POINTER_DINAMIC dans le destructeur. Ou ai-je tort ?

 

Si vous faites de l'héritage, vous obtiendrez beaucoup de méthodes inutiles. Et l'objet doit être privé. Vous n'allez pas le croire, mais le moyen le plus simple est de mettre des setters pour toutes les classes qui utilisent le gestionnaire de données.

Si tous les gestionnaires de données travaillent avec les mêmes paramètres, il est préférable de ne pas créer d'objets, mais de transmettre un pointeur vers un gestionnaire de données. Dans ce cas, un seul setter est nécessaire pour transmettre le pointeur.

 
Alexey Kozitsyn:

Merci pour l'exemple, c'est un peu compliqué jusqu'à présent, mais en général l'idée est claire. Une question se pose immédiatement : ok, si "un niveau d'imbrication" - ici c'est clair, mais s'il y aura plusieurs niveaux d'imbrication ?

Ajouté :

On ne sait pas non plus pourquoi le champ cIsDelData ? Après tout, vous pouvez simplement vérifier m_data par rapport à POINTER_DINAMIC dans le destructeur. Ou ai-je tort ?

Non, vous avez tort. Vous pouvez passer un pointeur à un objet dynamique et, oups, le tuer en toute sécurité.
Et à propos de la nidification. Vous créez une instance d'un objet là où vous en avez initialement besoin, et seulement les pointeurs plus loin, comme dans l'exemple ci-dessus. Si, en général, il est destiné à être un singleton dans le projet, vous pouvez faire un singleton, mais je n'en ai jamais fait en utilisant mql, donc je n'en ai pas eu besoin, je dois l'essayer.
 
Dmitry Fedoseev:
Vladimir Simakov:

Merci, je vais y réfléchir.

 
Vladimir Simakov:

Je le fais à peu près comme ça.

ce que signifie cette ligneCDataManager* m_data;

Les gars, je veux faire un truc comme ça. J'ai une 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 это дополнительное выражение которое будет дописываться в новый макрос

Par conséquent, j'aurai deux macros,foor etfoor1.

 
Seric29:

ce que signifie cette ligneCDataManager* m_data;

Les gars, je veux faire un truc comme ça. J'ai une macro.

Par conséquent, j'aurai deux macros,foor etfoor1.

Un pointeur vers un objet.

Ne le prenez pas mal, mais il est trop tôt pour que vous vous occupiez de telles macros. Tout d'abord, comprenez pourquoi j'ai fait ça :

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