Errori, bug, domande - pagina 2357

 
Ilya Malev:

Grazie per la risposta dettagliata, tuttavia non capisco un po' la logica.

1) Perché il compilatore percepisce il costrutto B* b1=a come una chiamata all'operatore di copia A::A(const A&), (invece di chiamare B::B(const A&), perché è la classe B a sinistra di operator=)

2) Perché il compilatore non ha generato l'avviso "copy constructor missing"?

3) perché una chiamata di metodo "semplice" è permessa per oggetti non esistenti (mentre un tentativo di chiamare direttamente A::f() genera un errore di compilazione "non è una chiamata di metodo statico")

1) Ho scritto che questo è un errore ovvio che sistemeremo comunque

2) il costruttore di copie è generato dal compilatore, se non è dichiarato dall'utente

3) la domanda non è molto chiara.
Dal contesto della discussione:
Si potrebbe discutere a lungo sull'opportunità o meno di "dereferenziare" un puntatore se non c'è accesso ad esso?
L'operazione di dereferenziazione (ottenere il puntatore effettivo dall'handle) è codice "interno" (non personalizzato) e costoso (rispetto a non averlo).
Perché eseguire la dereferenziazione se non ci sarà alcun accesso al puntatore?
Finché rimane così, l'operazione di dereferenziazione viene rimossa dall'ottimizzatore se non c'è accesso al puntatore.

 
Ilya Malev:

4) E perché il compilatore permette una "semplice" chiamata di metodo virtuale? Non credo che la virtualità debba dipendere dalla presenza o assenza di dati nell'oggetto

Stai confondendo la questione.

La chiamata devirtualizzazione è un metodo di ottimizzazione separato che non ha nulla a che fare con la presenza o l'assenza di campi in un oggetto.

 
Ilyas:

2) il costruttore di copie è generato dal compilatore, a meno che non sia dichiarato dall'utente

C'è un oggetto B a sinistra, perché il costruttore A::A(A&) è chiamato (o generato) per esso? Questo contraddice i principi di OOP
 
Alexey Navoykov:
C'è l'oggetto B a sinistra, perché il costruttore A::A() è chiamato per esso?

Perché in µl è così che gli operatori =, ==, !=, !&, &| e || si comportano sempre quando c'è un puntatore a sinistra e un "oggetto" a destra. E allo stesso tempo questi operatori non possono essere sovraccaricati sui puntatori.

Quindi, per favore, quando risolverete questo bug, rendete gli operatori di cui sopra sovraccaricabili per gli oggetti dinamici.

 
Metatrader 4 ha smesso di funzionare, funziona per un secondo circa quando mi avvio, poi appare una finestra di trading con un clic nell'angolo in alto a sinistra (Compra/Vendi) e poi l'applicazione si chiude.
Qualche suggerimento su come risolvere il problema?
Grazie in anticipo per il vostro aiuto.
 
Ilya Malev:

Perché è così che gli operatori =, ==, !=, !& e || si comportano sempre in µl quando c'è un puntatore a sinistra e un "oggetto" a destra.

Cosa c'entra il puntatore? Te l'ho già detto qui. Qui funziona allo stesso modo senza puntatore.
 
Alexey Navoykov:
C'è l'oggetto B a sinistra, perché il costruttore A::A(A&) è chiamato (o generato) per esso? Questo contraddice i principi di OOP

Sono completamente d'accordo con te e ho già scritto che questo è un errore che sarà corretto.

In questo caso, il compilatore ha raccolto un sovraccarico adeguato sull'ereditarietà, che non avrebbe dovuto essere fatto sulla costruzione dell'oggetto.

 
Ilyas:

Si può discutere a lungo sull'opportunità o meno di "dereferenziare" un puntatore se non c'è accesso ad esso.

L'operazione di dereferenziazione (ottenere un puntatore reale da un handle) è codice "interno" (non personalizzato) e costoso (rispetto a non averlo).
Perché eseguire la dereferenziazione se non ci sarà alcun accesso al puntatore?

Perché una lista di metodi virtuali fa parte delle informazioni di un oggetto, non meno importante dei dati stessi, e l'accesso ai metodi virtuali è un accesso al puntatore. Per esempio, se nel mio esempio scrivo

  A* aa=a;
  B* b1=a;   
  b1=aa;
  b1.f();

di nuovo otterrò B::f(), anche se questo codice si riferisce esplicitamente all'assegnazione dell'oggetto A*, che è stato "copiato" da A ed è stato referenziato da A*. Questa è una situazione più profonda che chiamare il costruttore di copie "sbagliato". Ma anche se l'oggetto non avesse avuto alcun metodo virtuale, avremmo comunque dovuto controllare la validità del puntatore quando vi si accede.

 
Alexey Navoykov:
C'è un oggetto B a sinistra, perché il costruttore A::A(A&) è chiamato (o generato) per esso ? Questo contraddice i principi di OOP

Sei sicuro che ci sia qualcosa che si chiama proprio lì? Ho controllato in x32:

class A {
public:
        A()           { Print(__FUNCSIG__); }
        A( const A& ) { Print(__FUNCSIG__); }
} a;
class B : public A {
public:
        B()           { Print(__FUNCSIG__); }
        B( const B& ) { Print(__FUNCSIG__); }
} *b = a;
void OnStart() {}

Risultato: A::A()
e nient'altro!

 
A100:

Sei sicuro che ci sia qualcosa che si chiama proprio lì? Ho controllato in x32:

Risultato: A::A()
e nient'altro!

OK, vado a controllare i dump del generatore/ottimizzatore per mettere i puntini sulle I