Questions sur la POO dans MQL5 - page 11

 
Dmitry Fedoseev:

Et en parlant d'oiseaux... les descripteurs sont aussi des pointeurs. Et vous savez, rien ne change du mot lui-même, qu'il s'agisse d'un descripteur, d'un pointeur, d'un identifiant.

l'application physique de ces mots a longtemps été cachée aux utilisateurs

Je pense que c'est plus ou moins comme ça.

- le descripteur - est lié à la méthode qui met en œuvre cette fonctionnalité dans le système

- un handle - tout est identique à un descripteur, mais l'OS l'implémente

- un pointeur et un identifiant sont destinés à fonctionner avec la mémoire physique

 
Dmitry Fedoseev:

Et si vous devez passer un pointeur à une fonction pour créer un objet dans la fonction, c'est ainsi que cela fonctionne :

class CObj{
   public:
   int f(){
      return(33);
   }
};

CObj * obj;

void OnStart(){
  z(obj);
  delete(obj);
}

void z(CObj & o){
   o = new CObj();
}
C'est en fait tout ce que vous vouliez savoir sur la POO, mais que vous n'osiez pas demander))).

Uh-huh, génie.

Ces 17 lignes sont en fait tout ce que vous avez besoin de savoir sur la qualification de Fedoseev en tant que programmeur.

2019.07.05 15:19:56.309 Accès au pointeur invalide dans 'test13.mq5' (11,5)

 
Vasiliy Sokolov:

Bon après-midi. La mémoire des ordinateurs a les mêmes performances, qu'elle soit utilisée dans un contexte de pile ou de tas. La gestion dynamique de la mémoire dépend elle-même de l'implémentation du collecteur de déchets : par exemple, il peut s'agir d'un comptage de références comme dans Python (version plus lente) ou d'une analyse des époques de génération des objets avec traversée du graphe d'exécution en arrière-plan (Net CLR). On ne sait pas quelle variante est utilisée dans MQL, mais on peut supposer qu'elle est extrêmement efficace, car l'utilisateur de MQL5 dispose directement de l'opérateur delete, ce qui simplifie grandement le travail de GC lui-même. Par conséquent, vos préoccupations concernant les frais généraux lors de l'utilisation de new sont sans fondement - n'hésitez pas à utiliser la mémoire dynamique.

Quant au "dépassement de pile", la seule façon de rencontrer ce cas dans les systèmes modernes est d'utiliser une récursion complexe ou de faire une erreur dans l'algorithme récursif. Un programme moderne fonctionne toujours en mode protégé OC dans l'espace d'adressage virtuel, avec un chargement dynamique des pages de mémoire, donc ne vous inquiétez pas : la pile ne débordera pas :)

Merci pour cette explication intelligente.
Pour une raison quelconque, je pensais qu'en mql, appeler sur la pile est plus rapide que sur le tas, d'autant plus que nous ne connaissons pas l'implémentation du collecteur d'ordures.
C'est pourquoi je me demande ce qu'il vaut mieux utiliser pour accélérer la création d'objets, l'auto ou le dynamique.
Oui, je comprends que tout dépend de la tâche spécifique, mais par exemple, prenons l'envoi de demandes de commerce.
Et notre tâche est de créer les objets les plus corrects pour une performance de traitement rapide.
Nous avons une classe définie par l'utilisateur avec des méthodes décrites de demandes de commerce.
Nous connaissons le nombre d'instances de la classe et ses méthodes.
Et comme vous le suggérez, "la pile ne s'arrêtera pas".

Ma question est donc la suivante : quelle méthode est la meilleure pour créer et supprimer des objets ? Automatiquement ou dynamiquement ?
J'ai eu l'idée de faire une gestion synthétique des objets automatiques en général.
C'est-à-dire déclarer les objets automatiques dans le corps de la fonction de l'utilisateur.
De cette façon, l'objet est créé sur la pile (en théorie, c'est plus rapide que le tas). Nous n'avons pas à nous soucier de la suppression automatique de l'objet car la variable objet est déclarée dans la fonction définie par l'utilisateur
et l'objet automatique sera en outre contrôlé pour sa destruction par la fonction utilisateur elle-même, conformément à la règle des variables dynamiques dans les fonctions.
C'est pourquoi je voudrais écouter les opinions adéquates des participants de cette branche, qui pense à cet égard.

 
TheXpert:

Mm-hmm, génie.

Ces 17 lignes sont en fait tout ce que vous devez savoir sur les qualifications de Fedoseev en tant que programmeur.

2019.07.05 15:19:56.309 Accès au pointeur invalide dans 'test13.mq5' (11,5)

Incroyable. Et je compile les deux sans erreur (en ce moment) et cela fonctionne correctement.

La prochaine fois, dessinez dans Photoshop.

 
Roman:

Merci pour cette explication intelligente.
Pour une raison quelconque, je pensais que l'appel sur la pile mql est plus rapide que sur le tas, d'autant plus que nous ne savons pas comment le collecteur d'ordures est implémenté.
C'est pourquoi je me demande ce qu'il vaut mieux utiliser pour accélérer la création d'objets, auto ou dynamique.
Oui, je comprends que tout dépend de la tâche spécifique, mais par exemple, prenons l'envoi d'ordres de négociation.
Et notre tâche est de créer les objets les plus corrects pour une performance de traitement rapide.
Nous avons une classe personnalisée avec des méthodes décrites de demandes de commerce.
Nous connaissons le nombre d'instances de la classe et ses méthodes.
Et comme vous le suggérez, "la pile ne s'arrêtera pas".

Ma question est donc la suivante : quelle méthode est la meilleure pour créer et supprimer des objets ? Automatiquement ou dynamiquement ?
J'ai eu l'idée de faire une gestion synthétique des objets automatiques en général.
C'est-à-dire déclarer les objets automatiques dans le corps de la fonction de l'utilisateur.
De cette façon, l'objet est créé sur la pile (en théorie, c'est plus rapide que le tas). Nous n'avons pas à nous soucier de la suppression automatique de l'objet car la variable objet est déclarée dans la fonction définie par l'utilisateur
et l'objet automatique sera en outre contrôlé pour sa destruction par la fonction utilisateur elle-même, conformément à la règle des variables dynamiques dans les fonctions.
C'est pourquoi je voudrais écouter les opinions adéquates des participants de cette branche, qui pense à cet égard.

Tu as bien pensé. L'accès aux objets créés avec new est beaucoup plus lent. Et il n'y a pas de ramasseur d'ordures ici.

 
Igor Makanu:

l'application physique de ces mots a longtemps été cachée aux utilisateurs

imho comme ça :

- descripteur - lié à la méthode qui met en œuvre cette fonctionnalité dans le système

- un handle - tout est identique à un descripteur, mais l'OS l'implémente

- un pointeur et un identifiant impliquent qu'il s'agit d'une opération dans la mémoire physique.

Et cela ne fait aucune différence pour nous de savoir comment cela fonctionne.

 

Un conseil sur une autre question. Si vous créez une classe enfant CMyButton à partir de CButton, vous pouvez créer un bouton et modifier ensuite ses propriétés en dehors de la classe. Ci-dessous, cela est fait dans OnInit().

Mais si je veux créer des champs supplémentaires dans la classe enfant et utiliser les propriétés intégrées de la classe CButton dans de nouvelles fonctions, comment puis-je le faire correctement ?

Dans la classe CButton, le membre de la classe m_button est déclaré dans la section private.

#include <Controls\Button.mqh>

class CMyButton : public CButton
{ 
  private: 

  public: 
              CMyButton(void){}; 
             ~CMyButton(void){}; 
             
        bool    isPrevState;        // состояние кнопки на предыд.тике, true - была нажата     
        void    setButton();        // создаем кнопку
        void    setProp();          // задаем в ходе программы свойства
}; 

void CMyButton::setButton(void)
{
  // как в этой функции создать кнопку? Я не могу вызвать метод Create()
}

//+------------------------------------------------------------------------------------------------------------------+
//| 
//+------------------------------------------------------------------------------------------------------------------+

CButton Btn;
CMyButton MyBtn;

int OnInit()
  {
  
   Btn.Create(0, "Btn", 0, 50, 50, 120, 75);
   Btn.Text("Standart");
   MyBtn.Create(0, "MyBtn", 0, 50, 200, 150, 225);
   MyBtn.Text("MyBtn");
   
   return(INIT_SUCCEEDED);
  }
 
Dmitry Fedoseev:

Oui, il supprime et écrit un message sur les fuites de mémoire, juste pour que les programmeurs qui écrivent les EA ne s'ennuient pas dans leur vie.

C'est intéressant de voir comment hier il y avait une fuite de mémoire et aujourd'hui il ne peut même pas y en avoir.

Et en parlant d'oiseaux... les descripteurs sont aussi des pointeurs. Et vous savez, le mot lui-même ne change rien, qu'il s'agisse d'un descripteur, d'un pointeur, d'un identifiant.

La fuite provient de l'espace d'adressage du processus. Si vous avez des fuites dans la boucle while(true), votre programme finira par se planter à la prochaine allocation de mémoire du tas, qui est épuisé.
 
Dmitry Fedoseev:

Et je compile les deux sans erreur (en ce moment) et cela fonctionne correctement.

Ouaip, déjà deux personnes sans lien entre elles font du photoshopping sur le crash de votre code ;)

Votre code ne peut pas fonctionner correctement, c'est évident par le code lui-même ;))

 
TheXpert:

Ouaip, deux personnes sans rapport entre elles sont déjà en train de photoshopper votre code ;)

Votre code ne peut pas fonctionner correctement, c'est évident à partir du code lui-même ;))

A l'instant, je voulais écrire la même chose))))