Errori, bug, domande - pagina 1890

 
fxsaber:
Qual è l'errore di esecuzione

Esatto, non si può guidare dal basso verso l'alto, ma solo dall'alto verso il basso. Questo è per la sicurezza.

Non si può fare un paragone con il C++ - lì qualsiasi cosa può essere ridotta a qualsiasi cosa.

 
Комбинатор:
In C++ funziona anche solo se un puntatore a una classe base punta al suo discendente.

Non so cosa intendi con questo, ma questo codice:

class CLASS1
{
public:
  int i;  
};

class CLASS2 : public CLASS1 {};

int main() {
  CLASS1 _object;
  CLASS2 *_ptr = (CLASS2*)&_object;  
  _ptr->i = 1;

   return 0;
}

funziona in C++, che è quello che ho scritto sopra. Ed ecco lo stesso codice (considerando la sintassi MQL):

class CLASS1
{
public:
  int i;  
};

class CLASS2 : public CLASS1 {};

int OnInit() {
  CLASS1 _object;
  CLASS2 *_ptr = dynamic_cast<CLASS2 *>(&_object);
  
  _ptr.i = 1;

   return 0;
}
non funziona più perché _ptr diventa NULL
Il che porta alla domanda: è un bug in MQL e sarà risolto o rimarrà così?
 
Renat Fatkhullin:

Esatto, non si può guidare dal basso verso l'alto, ma solo dall'alto verso il basso. Questo è per la sicurezza.

Non si può fare un paragone con il C++ - lì qualsiasi cosa può essere ridotta a qualsiasi cosa.


Capito ora, grazie per il chiarimento ))
 
Konstantin:

Non so cosa intendi con questo, ma questo codice:

Beh, cercate di capirlo. Cominciate a far funzionare dynamic_cast nei plus. Se lo capisci da solo, starai molto meglio.
 
Renat Fatkhullin:

Esatto, non si può guidare dal basso verso l'alto, ma solo dall'alto verso il basso.

Cosa vuol dire che non si può fare il cast da una classe base a una discendente?
 
Комбинатор:
Vuoi dire che non puoi fare il cast da una classe base a una discendente?

Sì, nel caso in cui la classe base non abbia un discendente effettivamente costruito.

 
Renat Fatkhullin:

Esatto, non si può guidare dal basso verso l'alto, ma solo dall'alto verso il basso. Questo è per la sicurezza.

Se portiamo il puntatore dall'alto al basso, cioè al genitore, e poi passiamo il puntatore da qualche altra parte nello scope, i campi del discendente sono disponibili lì?
 
Renat Fatkhullin:

Sì.

Renate, sai cos'è dynamic_cast?
 
Комбинатор:
Renat, sai cos'è dynamic_cast?

Naturalmente.

Guardate il pezzo di codice MQL5 discusso. Un'istanza base viene creata e poi cerca eroicamente di convertire via dynamiccast in discendente in violazione della sicurezza. Beh, è un peccato, ovviamente.

 

Lo stesso esempio è discusso e spiegato direttamente nella documentazione. Il cast dinamico in fase di esecuzione viene attivato solo dopo che il sistema di sicurezza e l'ammissibilità delle conversioni sono stati controllati. Ogni oggetto MQL5 ha tutte le meta-informazioni per il controllo dei diritti in fase di esecuzione. Questo non è un C++ vuoto.


Conversione dinamica del tipo usando l'operatore dynamic_cast

È possibile effettuare il cast dinamico dei tipi usando l'operatore dynamic_cast, che può essere applicato solo ai puntatori di classe. In questo caso, il controllo di correttezza dei tipi viene eseguito al momento dell'esecuzione del programma. Significa che quando si usa l'operatore dynamic_cast il compilatore non controlla il tipo di dati usato per la conversione. Se viene eseguita la conversione di un puntatore a un tipo di dati che non è il tipo di oggetto effettivo, il risultato sarà NULL.

dynamic_cast<tipo-id> ( espressione )

Il parametro type-id tra parentesi angolari deve essere un puntatore a un tipo di classe precedentemente definito . Iltipo di operando dell'espressione (al contrario del C++) può essere qualsiasi cosa tranne void.

Esempio:

classe CBar { };
classe CFoo :public CBar { };

voidOnStart( )
{
Bar CBar;
//--- il cast dinamico del tipo di puntatore *bar al puntatore *foo è permesso
CFoo *foo =dynamic_cast<CFoo*>(&bar);//--- nessun errore critico di esecuzione
Stampa(pippo);// foo=NULL
//--- provare esplicitamente a lanciare un riferimento dell'oggetto Bar in un oggetto Foo è proibito
pippo=(CFoo *)&bar;// si verificherà un errore critico di esecuzione
Stampa(pippo);// questa linea non sarà eseguita
}