Questions sur la POO dans MQL5 - page 44

 
Igor Makanu:

Je ne suis pas d'accord :

Veuillez mettre à jour vos connaissances sur ce que sont l'"opérateur d'affectation" et le "constructeur de copie", comment ils diffèrent, quand et comment ils sont appelés (explicitement et implicitement).
Dans le code, vous avez surligné en jaune le retour d'une variable locale depuis une fonction, ce qui a pour conséquence d'appeler le constructeur de copie par défaut (à ne pas confondre avec l'opérateur d'affectation).

Malheureusement, ce qu'est un "type de données complet" n'est pas tout à fait clair, pas plus que ce que vous essayiez de prouver avec votre code...
Je répète :"l'opérateur d'affectation MQL par défaut renvoie desdonnées de type void ;"

struct A{
   int x,y;
};

void OnStart(){
   A a, b;
   Print(typename(a = b));   // void
}
 
Koldun Zloy:

Faux.

Définissez simplement votre opérateur=, qui renvoie ceci, et voyez la différence.

Vous pouvez voir la différence lorsque le résultat de l'affectation est à nouveau attribué.

Si je définis operator=, je rate mon objectif initial d'appeler le ::= par défaut.

Cela semble être une question insoluble.


Sergey Dzyublik:

Ce qu'est le "type de données complet" n'est malheureusement pas très clair, pas plus que ce que vous essayiez de prouver avec votre code...

full est complet - la structure des données sera préservée et il n'y a pas besoin de contrôler la copie des structures si j'ajoute de nouveaux champs

 
Igor Makanu:

Si je définis l'opérateur =, je m'éloigne de mon objectif initial qui était d'appeler le ::= par défaut.

Avez-vous vraiment besoin de ce genre de mission ?

b = c = a;
 
Igor Makanu:

complete est complet - la structure des données sera préservée et il n'est pas nécessaire de contrôler la copie des structures si de nouveaux champs sont ajoutés

Ensuite, selon votre terminologie, l'appel de l'opérateur d'affectation par défaut peut donner un "type de données incomplet".
Le bogue de 2019.05.03 n'a jamais été corrigé: https://www.mql5.com/ru/forum/1111/page2451#comment_11556395

 
Koldun Zloy:

Avez-vous vraiment besoin d'une telle mission ?

purement en théorie, je veux savoir s'il s'agit d'une "nouvelle entité" plutôt que d'un opérateur =

Je n'en ai pas du tout besoin pour un usage pratique, je n'ai aucun problème à le mettre en 2 opérateurs.


Sergey Dzyublik:

Ensuite, selon votre terminologie, l'appel de l'opérateur d'affectation par défaut peut donner un "type de données incomplet".
Le bogue de 2019.05.03 n'a jamais été corrigé: https://www.mql5.com/ru/forum/1111/page2451#comment_11556395

"ma terminologie" consiste à demander, sans se plaindre,

mais l'intérêt d'utiliser l'opérateur par défaut = est qu'il est pratique de ne décrire que les champs de la structure, et tout est copié, y compris les dimensions des tableaux (bien que seulement avec des dimensions croissantes - le principe de travail est le même que dans ArrayCopy() )


Eh bien, si c'est un bug, ça doit l'être jusqu'à présent.

 

la question est purement théorique :

ont vu, peut-être dans SB, un appel de constructeur comme celui-ci :

class A{
public:   
   A(){Print(__FUNCTION__);}
};

class B{
public:   
   A a1,a2;
   B():a1(),a2() { Print(__FUNCTION__); }   
};

comment ce code serait-il différent :

class A{
public:   
   A(){Print(__FUNCTION__);}
};

class B{
public:   
   A a1,a2;
   B() { Print(__FUNCTION__); }   
};

Je l'ai décompressé, je ne vois pas de différence, alors soyez un peu plus précis - quoi ou pourquoi pouvons-nous utiliser un appel forcé au constructeur pour les objets a1 et a2 ?

quelle est la "commodité" de la première option ?

 
Igor Makanu:

la question est purement théorique :

ont vu, peut-être dans SB, un appel de constructeur comme celui-ci :

comment ce code serait-il différent :

Je l'ai décompressé, je ne vois pas de différence, alors soyez un peu plus précis - quoi ou pourquoi pouvons-nous utiliser un appel forcé au constructeur pour les objets a1 et a2 ?

quelle est la "commodité" de la première option ?

Les constructeurs peuvent avoir des paramètres et ils doivent être passés d'une manière ou d'une autre.

C'est-à-dire que tant qu'il n'y a pas de paramètres, il n'y a pas de différence, mais si vous utilisez le constructeur A(int arg), c'est une autre histoire.

 
Maxim Kuznetsov:

Les constructeurs ont des paramètres, et ils doivent être passés d'une manière ou d'une autre.

C'est-à-dire que tant qu'il n'y a pas de paramètres, la différence est insignifiante. Mais si vous avez le constructeur A(int arg), c'est une autre histoire

Vous avez probablement raison, cela dépend de l'objectif.

Je viens d'avoir des problèmes à cause de la première variante, lorsque j'ai voulu utiliser 2 constructeurs de la classe B et que j'ai reçu du code dupliqué dans les deux constructeurs - je les ai supprimés, et tout ce que j'ai obtenu est une partie du code qui était dans la première variante, et la question s'est posée de savoir où je l'ai vu et pourquoi je l'ai écrit de cette façon ;)))

 
Igor Makanu:

que donne ou pourquoi peut-on forcer les constructeurs des objets a1 et a2 à utiliser ?

Le nom correct du processus n'est pas "appel forcé du constructeur a1 et a2", mais initialisation des champs de la classe (non statique).
Obligatoire en cas de :

- Utilisation de champs de classe constants ;
- l'absence d'un constructeur par défaut pour les champs de la classe ;
- absence de tout autre moyen d'initialisation des objets que l'appel au constructeur (par exemple, l'opérateur d'affectation est supprimé) ;
-...

 

Quelqu'un peut-il expliquer en quoi cette initialisation des champs est meilleure que cela ?

CArray::CArray(void) : m_step_resize(16),
                       m_data_total(0),
                       m_data_max(0),
                       m_sort_mode(-1)
  {
  }

est meilleur que ça :

CArray::CArray(void)
  {
        m_step_resize=16;
        m_data_total=0;
        m_data_max=0;
        m_sort_mode=-1;
  }

Et quel est le but de toute façon ?

Raison: