Domande su OOP in MQL5 - pagina 44

 
Igor Makanu:

Non sono d'accordo:

Per favore, aggiorna la tua conoscenza di cosa sono "l'operatore di assegnazione" e il "costruttore di copia", come differiscono, quando e come vengono chiamati (esplicitamente e implicitamente).
Nel codice avete evidenziato in giallo il ritorno di una variabile locale da una funzione, che risulta nella chiamata del costruttore di copia predefinito (da non confondere con l'operatore di assegnazione).

Cosa sia un "tipo di dati completo", purtroppo, non è del tutto chiaro, né lo è quello che stavi cercando di dimostrare con il tuo codice...
Ripeto:"l'operatore di assegnazione predefinito di MQL restituiscedati di tipo void;".

struct A{
   int x,y;
};

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

Sbagliato.

Basta definire il vostro operator=, che restituisce questo, e vedere la differenza.

Puoi vedere la differenza quando il risultato dell'assegnazione viene assegnato di nuovo.

Se definisco operator=, perdo il mio obiettivo iniziale di chiamare il default ::=

Sembra essere una domanda irrisolvibile.


Sergey Dzyublik:

Che cos'è il "tipo di dati completo", purtroppo, non è molto chiaro, né lo è quello che stavi cercando di dimostrare con il tuo codice...

full è full - la struttura dei dati sarà conservata e non c'è bisogno di controllare la copia delle strutture se aggiungo nuovi campi

 
Igor Makanu:

Se definisco l'operatore =, mi allontano dal mio obiettivo iniziale di chiamare il default ::=

Hai davvero bisogno di questo tipo di incarico?

b = c = a;
 
Igor Makanu:

complete è completo - la struttura dei dati sarà conservata e non c'è bisogno di controllare la copia delle strutture se vengono aggiunti nuovi campi

Quindi, secondo la vostra terminologia, chiamare l'operatore di assegnazione predefinito potrebbe dare un "tipo di dati incompleto".
Il bug del 2019.05.03 non è mai stato risolto:https://www.mql5.com/ru/forum/1111/page2451#comment_11556395

 
Koldun Zloy:

Avete davvero bisogno di un tale incarico?

puramente in teoria, voglio sapere se è una "nuova entità" piuttosto che un operatore =

Non mi serve affatto per l'uso pratico, non ho problemi a metterlo in 2 operatori


Sergey Dzyublik:

Allora, secondo la vostra terminologia, chiamare l'operatore di assegnazione predefinito può dare un "tipo di dati incompleto".
Il bug del 2019.05.03 non è mai stato risolto:https://www.mql5.com/ru/forum/1111/page2451#comment_11556395

"la mia terminologia" è quella di chiedere, senza lamentarsi,

ma il punto di usare l'operatore predefinito = è che è conveniente descrivere solo i campi nella struttura, e tutto viene copiato, comprese anche le dimensioni degli array (anche se solo con dimensioni crescenti - il principio di lavoro è lo stesso di ArrayCopy() )


Beh, se si tratta di un bug, deve essere così lontano.

 

la questione è puramente teorica:

hanno visto, forse in SB, una chiamata al costruttore come questa:

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

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

come sarebbe diverso questo codice:

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

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

L'ho decompresso, non vedo alcuna differenza, allora sii un po' più specifico - cosa o perché possiamo usare una chiamata forzata al costruttore per gli oggetti a1 e a2?

qual è la "convenienza" della prima opzione?

 
Igor Makanu:

la questione è puramente teorica:

hanno visto, forse in SB, una chiamata al costruttore come questa:

come sarebbe diverso questo codice:

L'ho decompresso, non vedo alcuna differenza, allora sii un po' più specifico - cosa o perché possiamo usare una chiamata forzata al costruttore per gli oggetti a1 e a2?

qual è la "convenienza" della prima opzione?

I costruttori possono avere parametri e devono essere passati in qualche modo.

Cioè, finché non ci sono parametri, non c'è differenza, ma se usate il costruttore A(int arg), è una storia diversa

 
Maxim Kuznetsov:

I costruttori hanno dei parametri, e devono essere passati in qualche modo

Cioè, finché non ci sono parametri, la differenza è insignificante. Ma se avete il costruttore A(int arg), è una storia diversa

Probabilmente hai ragione - dipende dallo scopo

Mi sono appena messo nei guai a causa della prima variante, quando volevo usare 2 costruttori della classe B e ho ricevuto codice duplicato in entrambi i costruttori - li ho rimossi, e tutto quello che ho ottenuto è stata una parte di codice che era nella prima variante, ed è sorta la domanda dove l'ho visto e perché l'ho scritto in quel modo )))

 
Igor Makanu:

cosa dà o perché i costruttori degli oggetti a1 e a2 possono essere forzati?

Il nome corretto del processo non è "chiamata forzata del costruttore a1 e a2", ma inizializzazione dei campi (non statici) della classe.
Obbligatorio nei casi di:

- Usare campi di classe costanti;
- l'assenza di un costruttore predefinito per i campi della classe;
- assenza di qualsiasi altro modo di inizializzazione degli oggetti diverso dalla chiamata al costruttore (per esempio, l'operatore di assegnazione viene rimosso);
-...

 

Qualcuno può spiegare come questa inizializzazione dei campi sia migliore di questa:

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

è meglio di questo:

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

E comunque qual è il punto?