Erreurs, bugs, questions - page 1183

 
mql5:
La fonction ZeroMemory ne peut pas être utilisée pour cet objet.

Je vois. Mais pourquoi le compilateur affiche-t-il cette erreur non pas à l'endroit oùZeroMemory est utilisé mais à l'endroit où la classe est définie ? C'est déroutant. Je me suis déjà creusé la tête pour essayer de comprendre quelle est l'erreur et où elle se trouve. Assurez-vous que l'erreur est affichée au bon endroit. Par exemple, lors de la copie d'un objet contenant des éléments non autorisés à être copiés, l'erreur se produit exactement sur la ligne de copie et non quelque part dans la classe.

 
meat:

Pour en venir au côté pratique de tout cela, j'ai déjà rencontré un problème. Le code utilisait des objets statiques. Puis j'ai décidé de remplacer certains d'entre eux par des dynamiques. En conséquence, les opérations de comparaison et d'affectation ont commencé à fonctionner de manière très différente. Et ce problème était difficile à détecter car le programme continue à compiler et à fonctionner normalement mais pas comme il le devrait.

Je n'ai pas compris immédiatement le problème

class B {};

class A {
public:
        bool operator !=( A* a ) { Print( __FUNCTION__ ); return ( true  );  }
        bool operator !=( B* b ) { Print( __FUNCTION__ ); return ( false );  }
        bool operator >>( A* a ) { Print( __FUNCTION__ ); return ( true  );  }
        bool operator +( A* a )  { Print( __FUNCTION__ ); return ( false  ); }
        bool operator !()        { Print( __FUNCTION__ ); return ( true   ); }
};

void OnStart()
{
        A *a = new A;
        B *b = new B;
        if ( a != a ) Print( "1" );
        if ( a != b ) Print( "2" );
        if ( a >> a ) Print( "3" );
        if ( !a )     Print( "4" );
        delete( a );
        delete( b );
}
A partir de là, vous pouvez voir que (a != a) conduit à la comparaison de pointeurs alors que (a >> a) conduit à l'appel de l'opérateur >>( A* )

Il y a une contradiction.

Vous ne pouvez pas modifier le comportement de (a >> a) comme les autres opérateurs surchargés (à l'exception de == et !=) car cela rendrait la construction suivante impossible, puisque vous ne pouvez pas retourner (A) mais seulement (A*).

class A {
public:
        A *operator >>( string str ) { return ( GetPointer( this ) ); }
};

void OnStart()
{
        A *a = new A;
        a << "1234" << "мы" << "всю ночь" << "тусили"; //множественное применение оператора <<
}

Il sera également impossible d'utiliser pleinement les opérateurs surchargés car il n'existe pas d'opération de conversion de pointeur en objet (*a)

La seule chose qui reste à faire est de modifier le comportement de (== et !=)

Pour comparer les pointeurs (== et !=) entre eux et avec le nombre zéro (car les autres opérations sur les pointeurs n'ont aucun sens), il faut introduire une fonction spéciale comme (GetPointer) ou spécifier explicitement une conversion de type au compilateur

void OnStart()
{
        A *a = new A;
        B *b = new B;
        if ( ulong(a) != ulong(b) ) Print( "2" ); //хочу сравнить указатели
         if (       a  !=       b  ) Print( "2" ); //хочу вызвать operator !=( B* )

}

Ainsi, la possibilité d'utiliser pleinement les opérateurs surchargés sera préservée et la contradiction susmentionnée sera éliminée.

La seule exception raisonnable à la règle générale devrait rester operator=() car


class A {
public:
        A *operator =( A* a ) { return ( GetPointer( this ) ); }
};
void OnStart()
{
        A *a = new A;
        a = a; //не должно трактоваться компилятором как вызов operator=( A* ),
                // а должно остаться как присваивание указателю значения
}
 
Et bien sûr, la proposition d'utiliser (*a) au moins pour les opérateurs - revenir à la notation C++.
class A {
public:
        bool operator !=( A* a ) { Print( __FUNCTION__ ); return ( true  );  }
};

void OnStart()
{
        A *a = new A;
        if (  a !=  a ) Print( 1 ); //сравнение указателей
        if ( *a != *a ) Print( 2 ); //вызов operator !=( A* )
}

éliminerait toutes les contradictions d'un seul coup.

Correction : en fait, les contradictions ne sont éliminées que partiellement, parce que cette notation (*a) ne résout pas le problème de l'utilisation multiple des opérateurs (qui fonctionne maintenant avec succès avec tous les opérateurs, sauf == et !=) - donc la meilleure façon de comparer des pointeurs l'un à l'autre sur l'égalité/inégalité est encore d'utiliser une fonction spéciale - ou une conversion explicite au type ulong

 
A100, merci pour les messages, nous allons régler le problème.
 
Erreur de compilation
class A {
public:
      A( int a1 ) : a3( a1 ) { }
  static int a2;
        int a3;
};
int A::a2 = 1;

void OnStart()
{
        int b = A::a2;  //нормально
        A t1( b );     //нормально
        A t2( A::a2 ); //ошибка компиляции
        A* t3 = new A( A::a2 ); //нормально
}
si un argument de membre statique d'un constructeur (sauf new)
 
Le compilateur n'autorise pas les commentaires à l'intérieur de #define après transfert
#define  f( x )                   \
        ( x != 0 &&  /*comment*/\ 
          x != 1 )

c'est bien, et ça

#define  f( x )       \
        ( x != 0 &&  \ /*comment*/
          x != 1 )
erreur de compilation
 

En continuant le thème des pointeurs, il serait bien d'ajouter à MQL l'opérateur standard pour prendre un pointeur'&', il serait beaucoup plus pratique et compact que l'encombrant GetPointer.Ainsi, en ayant les opérateurs * et & dans notre arsenal, nous serons en mesure de définir explicitement les opérations nécessaires :

if (&a==&b) Print("Указатели равны");
if (*a==*b) Print("Объекты равны");


Et il y a plus à propos de cette esperluette. MQL manque de référence aux variables, surtout si l'on tient compte de l'utilisation limitée des pointeurs (uniquement vers les objets de classe). La fonction nécessite souvent l'accès à un élément de structure profondément imbriqué ou à un tableau multidimensionnel. Je dois écrire le chemin complet vers celui-ci à chaque fois, ce qui rend le code très lourd.Vous pouvez simplifier les choses en créant une référence et parfois vous devez juste "changer" le nom d'une variable localement pour des raisons de commodité. Cependant, qu'est-ce que j'explique ici ? Tout le monde sait déjà combien il est pratique d'utiliser des références mais maintenant vous devez utiliser #define à la place, ce qui n'est certainement pas bon.

Et nous avons également besoin de la possibilité de passer le résultat d'une fonction par référence, c'est-à-dire double& Func() { }

 

Facebook a récemment vu l'émergence du backlinking des publications des blogs :

1

 
meat:

En restant sur le thème des pointeurs, il serait bon d'ajouter à MQL un opérateur standard pour prendre un pointeur'&', ce serait beaucoup plus pratique et compact que l'encombrant GetPointer.Ainsi, en disposant des opérateurs * et &, nous pouvons définir sans ambiguïté les opérations nécessaires :

Le fait de n'adopter que (*a) pour faire référence aux fonctions membres n'apporte pas d'avantages évidents, mais conduit au contraire à l'impossibilité d'une application multiple simple et claire des opérateurs.

class A {
public:
        A *operator >>( string str ) { Print( __FUNCTION__); return ( GetPointer( this ) ); }
};

void OnStart()
{
        A *a = new A;
        a << "1234" << "мы" << "всю ночь" << "тусили"; //простая и понятная запись

Essayez de le réécrire en tenant compte de votre suggestion.

void OnStart()
{
        A *a = new A;
        *(*(*(*a << "1234") << "мы") << "всю ночь") << "тусили"; //запутанная запись
}

Vous ne pouvez pas utiliser l'objet lui-même au lieu du pointeur car l'opérateur <<(...) ne peut retourner qu'un pointeur vers l'objet.

Quelles opérations avec des pointeurs sont dénuées de sens ? - Seulement la comparaison entre eux et avec un nombre - par conséquent, ils doivent être négligés et placés dans une fonction spéciale (par exemple, bool ComparePointer( a,b)) afin de préserver la possibilité d'une utilisation multiple des opérateurs sans laquelle la surcharge d'opérateurs elle-même perd son sens.

 
A100:

Quelles opérations sur les pointeurs ne sont pas dénuées de sens ?

Tout ce pour quoi des références sont normalement utilisées.
Raison: