Question sur la dactylographie - page 4

 
Ilya Malev:

Le problème n'est pas très clair. L'initialisation de l'objet ne pourrait-elle pas être placée dans une méthode distincte comme Init(), peut-être même une méthode virtuelle ?

Oui, bien sûr. Impossible de class.get_int()/class.get_double()/class.get_string()/... ?)). Style, habitude ...

 
pavlick_:

Bien sûr, vous pouvez. Impossible de class.get_int()/class.get_double()/class.get_string()/. ?)). Style, habitude ...

Nous pouvons, mais écrivons d=var[x].get_double au lieu de d=var[x] partout où il y a le double d, var[] ;. Si nous devons faire preuve de masochisme, nous devrions le faire collectivement =))

 
Ilya Malev:

Donc, en fin de compte, on en arrive au souhait d'introduire dans mql la possibilité de surcharger l'opération de typage (y compris implicite), c'est-à-dire de définir un contexte d'appel de méthode et en fonction du type de valeur de retour attendu dans ce contexte d'appeler le code requis.

Ce n'est évidemment pas un standard C++, et en général, le bon côté du C++ (et il a été pris par les développeurs de MQL comme base) est que tout ce que le programmeur en C++ ne pouvait pas gérer explicitement, il devait travailler avec les pointeurs et écrire sontype typedef

un pointeur est juste un pointeur vers une adresse mémoire, vous pouvez toujours le passer en paramètre et l'obtenir comme résultat d'une fonction, le déréférencement d'un pointeur donne une valeur physique en octets de mémoire, la conversion d'un pointeur vers son nouveau type vous donne beaucoup d'octets de mémoire ))))

Dans MQL, les pointeurs sont difficiles à expliquer, mais ils sont là, les développeurs ont dit que la priorité est la protection des données, donc toutes les innovations qui pourraient conduire à des sorties du bac à sable sont exclues.



sur le sujet, j'ai malheureusement peu de pratique de l'utilisation des modèles (template), mais je pense que vous pouvez le faire :

1. écrire des fonctions surchargées qui renvoient le type requis comme résultat, et prennent ce type comme paramètre, c'est-à-dire comme ceci :

//+------------------------------------------------------------------+
int f(const int x)
  {
   return((int)1);
  };
//+------------------------------------------------------------------+
double f(const double x)
  {
   return((double)2);
  }
//+------------------------------------------------------------------+
string f(const string x)
  {
   return((string)3);
  }
//+------------------------------------------------------------------+
void OnStart()
  { 
   int    a=0;
   double b=0;
   string c="0";
   a = f(a);
   b = f(b);
   c = f(c);
   Print("a = ",a);
   Print("b = ",b);
   Print("c = ",c);
}

2. maintenant la fonction f() doit être enveloppée dans un modèle et cacher le paramètre x - si les modèles vous permettent de le faire, alors l'appel sera a=f() - visuellement tout sera beau, comme si vous tapiez

 
Igor Makanu:

il ne s'agit manifestement pas d'une norme C++

Je pense que vous avez tort - bien que je n'aie pas écrit en C++ "pur" depuis longtemps, il y a beaucoup d'exemples de code comme celui-ci sur le web.

class A
{
public:
    operator int()const;
};

A::operator int()const
{
    return 0;
}
 
Ilya Malev:

Je pense que vous avez tort - bien que je n'aie pas écrit en C++ "pur" depuis longtemps, mais le web est plein d'exemples de code comme celui-ci

Mais que faire s'il s'agit d'un type complexe? - Une structure ou un tableau ? En C++, cette question était résolue en utilisant des pointeurs vers leur type, le compilateur renvoyant physiquement l'adresse mémoire et le déréférencement du pointeur garantissant que les données étaient traitées correctement.

 
Igor Makanu:

Cet exemple fonctionnerait correctement, mais que faire s'il s'agit d'un type complexe? - En C++, ce problème a été résolu avec des pointeurs sur son type, le compilateur renvoyant physiquement l'adresse mémoire et le déréférencement du pointeur assurant la gestion correcte des données.

Un tel exemple ne fonctionnerait pas correctement dans mql, malheureusement.

Un type, une structure ou un tableau complexe peut surcharger ce dont vous avez besoin, il ne nécessite pas de surcharge de conversion de type...

 
Ilya Malev:

Dans mql, un tel exemple ne fonctionnerait pas correctement, malheureusement.

Eh bien, oui, je viens de voir, vous voulez surcharger la conversion de type, l'aide MQL dit clairement qu'il est permis de surcharger, et les opérations unaires sont surchargées seulement comme unaire et binaire, respectivement, je travaillais avec des matrices, j'ai essayé de surcharger ^ - cela ne fonctionne pas, j'ai dû utiliser !

  • бинарные +,-,/,*,%,<<,>>,==,!=,<,>,<=,>=,=,+=,-=,/=,*=,%=,&=,|=,^=,<<=,>>=,&&,||,&,|,^;
  • unaire +,-,++,--,~ ;
  • opérateur d'affectation = ;
  • opérateur d'indexation [].


J'ai regardé à nouveau mon exemple - le compilateur ne permet pas d'envelopper mon exemple dansun modèle. Je peux retourner((1/x) - et je peux donner une chaîne de caractères comme paramètre x. Habituellement, tous les compilateurs C vérifient au moment de la compilation la correspondance des types, et MQL ne permet pas d'envelopper des solutions ambiguës dans des modèles.

A mon avis, votre problème - post 1 du sujet, en MQL peut être résolu correctement, seulement en décrivant toutes lesfonctions surchargées. Ensuite, tous les types de variables qui sont passées et retournées et toutes les fonctions surchargées seront vérifiées au moment de la compilation.

 
Igor Makanu:

Oui, je viens de voir, vous voulez surcharger la conversion de type, l'aide MQL dit clairement que la surcharge est autorisée, et les opérations unaires sont surchargées seulement comme unaire et binaire respectivement, je travaillais avec des matrices, j'ai essayé de surcharger ^ - cela ne fonctionne pas, j'ai dû utiliser !

Je peux affirmer à 99% qu'il n'existe pas de situation où ^ ne peut pas surcharger, alors que ! Et la surcharge ne dépend pas du type d'opérateur. Vous avez dû mal comprendre quelque chose. Il suffit d'afficher cet exemple ici, mais si vous l'avez déjà oublié, il vaut mieux ne pas le faire).

La seule restriction que j'ai rencontrée en ce qui concerne les types d'opérateurs est une interdiction de surcharger les opérateurs logiques ==, !=, ! et = appliqués aux pointeurs (any_type * ). Pour les surcharger correctement, il faut travailler soit avec des autobjets, soit avec des structures. Ces derniers mois, j'ai mangé beaucoup de chiens sur ces trucs, donc je peux parler avec confiance :)

 
Ilya Malev:

Je peux affirmer à 99 % qu'il n'existe aucune situation où ^ ne surcharge pas, mais où ! surcharge. Et la capacité de surcharge ne dépend pas du type d'opérateur. Vous avez dû mal comprendre quelque chose. Il suffit d'afficher cet exemple ici, mais si vous l'avez déjà oublié, il vaut mieux ne pas le faire).

La seule restriction que j'ai rencontrée en ce qui concerne les types d'opérateurs est une interdiction de surcharger les opérateurs logiques ==, !=, ! et = appliqués aux pointeurs (any_type * ). Pour les surcharger correctement, il faut travailler soit avec des autobjets, soit avec des structures. Ces derniers mois, j'ai mangé beaucoup de ces trucs, donc je peux dire avec confiance :)

#include <Math\Alglib\linalg.mqh>
class Matrix
  {
public:
   CMatrixDouble     M;
   int               row;//m_strok;
   int               col;//n_stolb;
   void              Matrix(void)         {                             }
   void              Matrix(int m,int n)  { M.Resize(m,n); row=m;col=n; }
   //----      умножение матриц
   Matrix operator*(const Matrix &B){Matrix res(this.row,B.col);CAblas::RMatrixGemm(this.row,B.col,this.col,1.0,this.M,0,0,0,B.M,0,0,0,0,res.M,0,0);return(res);  }
   //----      транспонирование матрицы
   Matrix operator!(void){Matrix res(this.col,this.row);CAblas::RMatrixTranspose(this.row,this.col,this.M,0,0,res.M,0,0);return(res);                             }
   //----      нулевая матрица
   void              zeros(int r,int c) {this.M.Resize(r,c);this.row=r;this.col=c;for(int i=0;i<r;i++){for(int j=0;j<c;j++){this.M[i].Set(j,0.0);}}               }
   //----      вывод в журнал матрицы
   void MatrixPrint(string  separator="|",uint digits=3){string s,sep=" "+separator+" ";for(int i=0;i<row;i++){s=separator;for(int j=0;j<col;j++) s+=DoubleToString(M[i][j],digits)+sep;Print(s);Sleep(123);}}
private:
   void              Matrix(const Matrix &R) { this=R;                                                                                                            }
  };

Dans la manipulation "classique" des matrices, vous devez utiliser l'opérateur ^ pour transposer les matrices, voici mon exemple - j'ai porté la méthode SSA de Matlab, c'est la multiplication, l'affectation et la transposition de matrices la plus simple basée sur CMatrixDouble - elle ... il ne connaît pas la taille des matrices qu'il stocke (combien de lignes et de colonnes il a).

 
P.S., ah, c'est à dire que vous vouliez surcharger un opérateur binaire comme un opérateur unaire (2ar comme 1ar), alors oui, bien sûr, il ne le fera pas. La seule exception est []