Domanda sulla digitazione - pagina 4

 
Ilya Malev:

Non è molto chiaro quale sia il problema. Non si potrebbe mettere l'inizializzazione dell'oggetto in un metodo separato come Init(), magari anche virtuale?

Sì, certo. Impossibile class.get_int()/class.get_double()/class.get_string()/... ?)). Stile, abitudine ...

 
pavlick_:

Certo, è possibile. Impossibile class.get_int()/class.get_double()/class.get_string()/. ?)). Stile, abitudine ...

Possiamo, ma scriviamo d=var[x].get_double invece di d=var[x] ovunque ci sia il doppio d, var[];. Se dobbiamo impegnarci nel masochismo, dovremmo farlo collettivamente =))

 
Ilya Malev:

Quindi, alla fine si riduce al desiderio di introdurre in mql la possibilità di sovraccaricare l'operazione di tipizzazione (anche implicita), cioè definire un contesto di chiamata del metodo e a seconda del tipo di valore di ritorno previsto in questo contesto chiamare il codice richiesto.

Questo ovviamente non è uno standard C++, e in generale, la cosa buona del C++ (ed è stato preso dagli sviluppatori MQL come base) è che tutto ciò che in C++ il programmatore non poteva gestire esplicitamente, doveva lavorare con i puntatori e scrivere il suo tipotypedef

un puntatore è solo un puntatore a un indirizzo di memoria, puoi sempre passarlo come parametro e ottenerlo come risultato di una funzione, dereferenziando un puntatore si ottiene un valore fisico in byte di memoria, convertendo un puntatore al suo nuovo tipo si ottengono molti byte di memoria ))))

In MQL, i puntatori sono difficili da dire perché, ma sono lì, gli sviluppatori hanno detto che la priorità è la protezione dei dati, quindi tutte le innovazioni che potrebbero portare ad uscite dalla sandbox sono escluse



sull'argomento, purtroppo ho poca pratica nel lavorare con i modelli ( template ), ma ho il sospetto che si possa fare:

1. scrivere alcune funzioni sovraccaricate che restituiscono il tipo richiesto come risultato, e prendono quel tipo come parametro, cioè così:

//+------------------------------------------------------------------+
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. ora la funzione f() deve essere avvolta in un template e nascondere il parametro x - se i template permettono di farlo, allora la chiamata sarà a=f() - visivamente tutto sarà bello, come scrivere

 
Igor Makanu:

ovviamente non è uno standard C++

Penso che ti sbagli - anche se non ho scritto in C++ "puro" per molto tempo, ci sono molti esempi di codice come questo sul web

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

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

Penso che ti sbagli - anche se non ho scritto in C++ "puro" per molto tempo, ma il web è pieno di esempi di codice come questo

Ma cosa succede se è un tipo complesso? - Una struttura o un array? In C++ questo è stato risolto usando puntatori al loro tipo, fisicamente il compilatore restituiva l'indirizzo di memoria e dereferenziando il puntatore si assicurava che i dati fossero gestiti correttamente

 
Igor Makanu:

Questo esempio funzionerebbe correttamente, ma se fosse un tipo complesso? - In C++ questo è stato risolto con puntatori al suo tipo, fisicamente il compilatore restituiva l'indirizzo di memoria e la dereferenziazione del puntatore forniva la corretta gestione dei dati

Un tale esempio non funzionerebbe correttamente in mql, purtroppo.

Un tipo complesso, una struttura o un array può sovraccaricare qualsiasi cosa, non richiede un sovraccarico di conversione dei tipi...

 
Ilya Malev:

In mql tale esempio non funzionerebbe correttamente, purtroppo.

Beh, sì, ho appena visto, vuoi sovraccaricare la conversione dei tipi, l'aiuto di MQL dice chiaramente che è permesso sovraccaricare, e le operazioni unarie sono sovraccaricate solo come unarie e binarie, rispettivamente, stavo lavorando con le matrici, ho provato a sovraccaricare ^ - non funziona, ho dovuto usare !

  • бинарные +,-,/,*,%,<<,>>,==,!=,<,>,<=,>=,=,+=,-=,/=,*=,%=,&=,|=,^=,<<=,>>=,&&,||,&,|,^;
  • unario +,-,++,--,~;
  • operatore di assegnazione =;
  • operatore di indicizzazione [].


Ho guardato di nuovo il mio esempio - il compilatore non permette di avvolgere il mio esempio inun template. Posso restituire((1/x) - e posso dare una stringa come parametro x. Di solito tutti i compilatori C in fase di compilazione controllano la corrispondenza dei tipi, e MQL non permette di avvolgere soluzioni ambigue nei template.

imho, il tuo problema - post 1 dell'argomento, in MQL può essere risolto correttamente, solo descrivendo tutte lefunzioni sovraccaricate. Poi, tutti i tipi di variabili che vengono passati e restituiti e tutte le funzioni sovraccaricate saranno controllate in fase di compilazione.

 
Igor Makanu:

Sì, ho appena visto che vuoi sovraccaricare la conversione dei tipi, l'aiuto MQL dice chiaramente che l'overloading è permesso, e le operazioni unarie sono sovraccaricate solo come unarie e binarie rispettivamente, stavo lavorando con le matrici, ho provato a sovraccaricare ^ - non funziona, ho dovuto usare !

Posso affermare per il 99% che non esiste una situazione in cui ^ non possa sovraccaricarsi, mentre ! E il sovraccarico non dipende dal tipo di operatore. Devi aver frainteso qualcosa. Basta postare qui questo esempio, ma se l'avete già dimenticato e lo dimenticate, è meglio di no).

L'unica restrizione che ho incontrato riguardo ai tipi di operatori è un divieto di sovraccarico degli operatori logici ==, !=, ! e = applicato ai puntatori (any_type * ). Sovraccaricarli correttamente richiede di lavorare con autobjects o strutture. Solo negli ultimi mesi ho mangiato un sacco di cani su queste cose, quindi posso parlare con sicurezza :)

 
Ilya Malev:

Posso dire per il 99% che non c'è situazione in cui ^ non sovraccarica, ma ! sì. E la capacità di sovraccarico non dipende dal tipo di operatore. Devi aver frainteso qualcosa. Basta postare qui questo esempio, ma se l'avete già dimenticato e lo dimenticate, è meglio di no).

L'unica restrizione che ho incontrato riguardo ai tipi di operatori è un divieto di sovraccarico degli operatori logici ==, !=, ! e = applicato ai puntatori (any_type * ). Sovraccaricarli correttamente richiede di lavorare con autobjects o strutture. Negli ultimi mesi ho mangiato molti di questi trucchi, quindi posso dire con sicurezza :)

#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;                                                                                                            }
  };

Nella gestione "classica" delle matrici dovete usare l'operatore ^ per trasporre le matrici, ecco il mio esempio - ho portato il metodo SSA da Matlab, è la più semplice moltiplicazione, assegnazione e trasposizione di matrici basata su CMatrixDouble - ... non conosce la dimensione delle matrici che memorizza (quante righe e colonne ha).

 
P.S., ah, cioè volevi sovraccaricare un operatore binario come uno unario (2ar come 1ar), allora sì, certo che no. L'unica eccezione è []