MQL5 Le compilateur ne fait pas la distinction entre une classe et un pointeur vers celle-ci - page 12

 
Georgiy Merts:

Non. Il est clair que, dans ce cas, la variable doit être supprimée à la sortie du bloc.

Je parle d'objets créés par de nouveaux :

La norme C# spécifie :"Les objets de type valeur, comme les structures, et les objets de type référence, comme les classes, sont tous deux détruits automatiquement, mais les objets de type valeur sont détruits lorsque le contexte qui les contient est détruit, tandis que les objets de type référence sont détruits par le collecteur de déchets indéfiniment après la suppression de la dernière référence à ces objets."

Ici, je n'aime pas ce "temps imprévisible". Même si j'admets que le collecteur d'ordures peut supprimer l'objet de manière beaucoup plus efficace que je ne le fais moi-même dans le destructeur de la classe qui l'a créé.

Logiquement, puisque personne ne le référence, cela signifie que personne n'a plus besoin de l'objet, il sera supprimé lors de la prochaine collecte de déchets. Le délai est imprévisible, mais vous pouvez demander au GC de le construire immédiatement. Mais il s'agit également d'une demande, pas d'une commande ;)))

 
Georgiy Merts:

Je ne dis pas que le collecteur d'ordures va supprimer un objet vivant ou un pointeur. Je dis qu'il l'enlèvera quand il le voudra.

Sharp a une fonction qui protège l'objet contre la suppression par le collecteur de déchets.

https://docs.microsoft.com/ru-ru/dotnet/api/system.runtime.interopservices.gchandle.alloc?view=netcore-2.0

// for standalone object
public byte[] RawSerialize(object objAny)
{
int rawsize = Marshal.SizeOf(objAny);
byte[] m_obj = new byte[rawsize];

        GCHandle hObj = GCHandle.Alloc(m_obj, GCHandleType.Pinned);

        Marshal.StructureToPtr(objAny, hObj.AddrOfPinnedObject(), false);
        hObj.Free();

return (m_obj);
}
GCHandle.Alloc Method (System.Runtime.InteropServices)
GCHandle.Alloc Method (System.Runtime.InteropServices)
  • dotnet-bot
  • docs.microsoft.com
Выделяет дескриптор для указанного объекта.Allocates a handle for the specified object.
 
Alexey Navoykov:

Et maintenant vous essayez désespérément d'inventer des excuses pour expliquer pourquoi vous n'étiez pas au courant ;)

Quelle différence cela fait-il s'ils l'ont introduit immédiatement ou des mois plus tard ? Vous ne l'auriez pas su et ne le sauriez toujours pas si je ne vous l'avais pas dit).

J`ai peur de brûler de honte, mais je ne connaissais pas & & jusqu`à récemment, jusqu`à ce que je le voie quelque part sur fxsaber. J'utiliserais GetPointer autrement.

Mais j'ai fait attention à l'absence de possibilité de surcharger certaines opérations avec des objets en septembre quelque part et à ce moment-là j'ai essayé de résoudre ce problème par moi-même et certaines personnes m'ont écrit que cette possibilité n'existe pas. Et maintenant il s'avère qu'elle existe, donc je me demande quand exactement elle est apparue (et pourquoi elle n'est pas dans l'aide).

 
SemenTalonov:

Ils iront probablement dans la direction de C# où le "code géré" n'a pas de pointeurs et où tout a un objet, même les types simples bool int double, etc.

Ce serait bien, mais il est peu probable qu'ils changent quoi que ce soit dans ce sens, car il s'agit d'un changement complet dans le concept du langage terminal, et de telles choses sont rarement faites.

SemenTalonov:

Exactement selon IMHO, il est nécessaire de ne pas oublier de quoi il s'agit exactement (objet ou pointeur vers celui-ci).

Pour ne pas oublier, vous devez décider dès le début quand vous utilisez des objets et quand vous utilisez des pointeurs (idéalement, jamais d'objets et toujours des pointeurs).

Et c'est idiot d'écrire à chaque fois des lettres supplémentaires pour cela (surtout pour s'embêter avec les parenthèses).

De plus, dans ce cas, l'opération d'assignation que vous décrivez n'est pas utilisée par rapport à un objet mais par rapport à son champ non-objet ce qui, en principe, exclut la probabilité d'une erreur (le type de pointeur dans une telle opération n'a pas d'importance).

 
Ilya Malev:

Pour ne pas oublier, vous devez décider dès le début quand vous utilisez des objets et quand vous utilisez des pointeurs (idéalement, jamais d'objets et toujours des pointeurs).

Lorsque vous ouvrez votre propre code après une longue période (un an ou deux) et que vous vous reprochez de ne pas avoir laissé de commentaires aux endroits "délicats", ou que vous ne savez pas distinguer les objets des pointeurs, c'est comme une perte totale. Je ne suis pas non plus d'accord pour refuser l'utilisation des auto-objets. Leur utilisation rend le code compact et réduit les inquiétudes quant au sort de l'objet une fois qu'il est devenu obsolète. De plus, je suis sûr que la durée de vie d'un tel objet est connue à l'avance par le compilateur et que ce dernier peut donc fournir un code plus optimisé qu'en cas de création dynamique.

Ilya Malev:

Et il est tout simplement stupide d'écrire des lettres supplémentaires à chaque fois pour cela (surtout pour s'embêter avec les parenthèses).

De plus, dans le cas que vous décrivez, l'opération d'assignation est utilisée non pas par rapport à un objet mais par rapport à son champ non-objet, ce qui exclut fondamentalement la probabilité d'une erreur (le type de pointeur dans une telle opération n'a pas d'importance).

Ce non-sens vient du fait qu'en MQL, il n'y a pas d'autre moyen de désigner l'accès à un objet par un pointeur. En C/C++, bien sûr, ce serait plus laconique.

pA->iValue

La raison de l'absence de la flèche est probablement la même que pour le'*' à l'origine (inconnu). Dans Qt (et probablement aussi dans VS), l'éditeur remplace automatiquement '.' par '->' si l'objet est accédé par un pointeur, c'est-à-dire sans travail supplémentaire. Je ne doute pas que MQ puisse ajouter une telle fonctionnalité à l'éditeur, si on le souhaite. Il s'avère que dans cet exemple, le seul signe de l'utilisation d'un pointeur est le préfixe "p" dans le nom. Et c'est seulement parce que je n'ai pas oublié. Si tout le monde fait preuve de tact, c'est très bien.)

C'est-à-dire que les fragments de code potentiellement dangereux doivent être explicitement marqués. Vous n'avez pas besoin de vous en souvenir, vous devez les voir. La nécessité d'une telle "formalisation des relations" avec les objets serait plus claire sur des échantillons plus complexes que ceux donnés ci-dessus. Par exemple, lorsqu'un membre de la classe est lui-même un pointeur vers quelque chose.

En fournissant une manière uniforme de traiter lesPOINTER_AUTOMATIC etPOINTER_DYNAMIC, on nous donne l'idée trompeuse que ces types de pointeurs sont similaires. Mais en fait, ce sont des entités différentes qui nécessitent un traitement différent.C'est le sujet principal de cette branche. Laplus évidente est bien sûr : alors quePOINTER_AUTOMATIC pointe toujours vers un objet réel,POINTER_DYNAMIC peut aussi être vide.

Et je vais juste vous rappeler toutes les différentes variations de l'accès aux données (bien que C/C++, tant que nos chemins correspondent)

OpérateurSyntaxeRechargeableMis en œuvre enCExemple
Membre du type TDéfinition en dehors de la classe
Accès à un élément de tableaua[b]OuiOuiRT::opérateur[](Sb) ;
s/o
Référence indirecte ("objet pointépar a")*aOuiOuiRT::operator*() ;Opérateur R*(Ta) ;
Référence ("adressea")& aOuiOuiR opérateurT::operator&() ;Opérateur R&(Ta);
Référencement d'un membre de la structure ("le membre b de l'objet pointé para")a-> bOuiOuiR*T::operator->() ;[note 5].
N/A
Référence à un membre d'une structure ("b member of objecta")a. bNonOuis/o
Membre pointé par b dans un objet pointé para[note 6].a->*bOuiNonR opérateurT::operator->*(Sb) ;Opérateur R->*(Ta, Sb);
Le membre pointé par b dans l'objetaa.*bNonNonN/A
 
SemenTalonov:

La plus évidente bien sûr : siPOINTER_AUTOMATIC pointe toujours vers un objet réel, alorsPOINTER_DYNAMIC peut aussi être vide.

Si le "plus évident" est déjà faux, cela vaut-il la peine d'examiner sérieusement et de répondre à tout le reste ?

POINTER_AUTOMATIC n'est pas le type de la variable, c'est son statut. Le moment suivant, son statut peut être tout à fait différent. Y compris POINTER_INVALID, bien sûr.
 
Ilya Malev:

Si le "plus évident" est déjà faux, cela vaut-il la peine de considérer sérieusement et de répondre à tout le reste ?

J'aimerais avoir des précisions à ce sujet, si possible

 
Ilya Malev:
POINTER_AUTOMATIC n'est pas un type de variable mais son statut. Au moment suivant, son statut peut être très différent.

Certainement pas un type. Vous voulez dire que l'auto-objet devient un pointeur avec le statutPOINTER_DYNAMIC, par exemple ? Il s'agit de l'étatPOINTER_INVALID lors de la déclaration d'un pointeur, par exemple.

 
SemenTalonov:

J'aimerais avoir des précisions à ce sujet, si possible.

C'est juste que dans MKL, ce n'est apparemment pas la même chose qu'en C++. Ici, un pointeur n'est pas du tout un type de données distinct, donc les deux sont des objets et une variable contient son handle. Une variable a une propriété constante cachée (si elle est déclarée sans *), mais cela n'en fait pas essentiellement une variable d'un type différent, cela interdit seulement de lui assigner un handle différent.

 

C'est-à-dire, déclarer

   A* const b=new A;

Et vous aurez exactement le même "auto-objet", mais vous le supprimerez vous-même.