Sì, C++ non conta molte cose, ma il punto è che l'inizializzazione dei membri statici probabilmente non è nell'ordine in cui sono inizializzati, ma nell'ordine in cui sono dichiarati.
L'ho reso troppo facile - non ho spostato la costante - come potete vedere ora tutto è chiaro - una costante è inizializzata da un'altra:
class A {
protected: //если заменить на public: то все работает
staticconstint s1;
staticconstint s2;
};
constint A::s1 = 0x1;
constint A::s2 = A::s1; //ошибка компиляции
Il compilatore indica come errore che il membro s1 è protetto. Se sostituiamo protected con public, tutto funziona alla perfezione. Ma essere protetti non ha niente a che fare con l'ordine di inizializzazione o di assegnazione, né con la possibilità di inizializzazione con un valore particolare
Probabilmente un errore nella sequenza di chiamata
class A {
public:
A *operator<<( int x ) { Print( x ); return ( GetPointer( this )); }
A *operator<<( string s ) { Print( s ); return ( GetPointer( this )); }
};
int f( int& x ) { return ( x = 4 ); }
voidOnStart()
{
Print( "" );
A a;
int x = 3;
a << "(1)" << "(2)" << "(3)"; // Результат: (1) (2) (3) //нормально
a << x << f( x ) << x; // Результат: 4 4 3 ??? как же так?
}
Nell'ultimo caso mi aspettavo il risultato: 3 4 4 simile al precedente. Non è normale che alcuni tipi abbiano una sequenza di chiamate e altri ne abbiano una diversa.
A proposito - la sequenza delle operazioni di spostamento da sinistra a destra è anche definita in MQL5 stesso, come conferma l'esempio:
voidOnStart()
{
int a = 0x1;
int b = a << 2 << a; //b = 8int c = (a << 2) << a; //c = 8int d = a << (2 << a); //d = 16Print ( "b=", b, ", c=", c, ", d=", d );
}
Il problema è cheRefreshRealSymbols() viene eseguito normalmente se chiamato nel costruttore diCSymbolsCollection.
Tuttavia, chiamando SymbolsCollection.RefreshRealSymbols(); in OnInit(); si ottiene:
invalid pointer access in 'SymbolsCollection.mqh' (55,22)
L'errore punta alla linea CleanSymbolsArray(myRealSymbols); nel corpo del metodo CSymbolsCollection::RefreshRealSymbols(), la posizione è proprio dopo la parentesi aperta.
In effetti, ha senso, perché ciò che è scritto sembra un po' delirante.
Il C++ non lo considera in questo modo.
Sì, C++ non conta molte cose, ma il punto è che l'inizializzazione dei membri statici probabilmente non è nell'ordine in cui sono inizializzati, ma nell'ordine in cui sono dichiarati.
Dovrò leggere la norma su questo argomento.
https://www.mql5.com/ru/docs/basis/variables/initialization
L'ho reso troppo facile - non ho spostato la costante - come potete vedere ora tutto è chiaro - una costante è inizializzata da un'altra:
Il compilatore indica come errore che il membro s1 è protetto. Se sostituiamo protected con public, tutto funziona alla perfezione. Ma essere protetti non ha niente a che fare con l'ordine di inizializzazione o di assegnazione, né con la possibilità di inizializzazione con un valore particolare
Dovrò leggere la norma su questo.
Sono d'accordo, in generale il compilatore non è la stessa cosa del compilatore e bisogna risolverlo.
Ecco un altro esempio
Il compilatore MQL qui non vuole inizializzare l'array con il valore const int (enum - passa)
Ancora una volta mi sto appellando al fatto che C++ lo copia e lo inizializza correttamente.
Probabilmente un errore nella sequenza di chiamata
In C++, l'ordine di valutazione degli operandi di un'espressione è UB. Perché si basa su un ordine specifico?
è stato emesso come "parola Ciao" ?
Questo è ciò che succede in questo caso per un operatore sovraccaricato per il tipo int, mentre per il tipo stringa tutto viene emesso normalmente.
Inoltre, non ha niente a che fare con il C++. Supponiamo che tu abbia scritto nel tuo codice
E avete queste funzioni eseguite in ordine inverso o in tutti per diversi tipi di argomenti - in un ordine arbitrarioSaluti!
Aiutami a risolvere il problema dell'accesso al puntatore non valido.
In OnInit() abbiamo:
SymbolsCollection = new CSymbolsCollection(); SymbolsCollection.RefreshRealSymbols();Il metodoCSymbolsCollection::RefreshRealSymbols() ha una chiamataCleanSymbolsArray(myRealSymbols);
Questi metodi e variabili sono dichiarati nella classe come:
Il problema è cheRefreshRealSymbols() viene eseguito normalmente se chiamato nel costruttore diCSymbolsCollection.
Tuttavia, chiamando SymbolsCollection.RefreshRealSymbols(); in OnInit(); si ottiene:
L'errore punta alla linea CleanSymbolsArray(myRealSymbols); nel corpo del metodo CSymbolsCollection::RefreshRealSymbols(), la posizione è proprio dopo la parentesi aperta.
Qualche idea?
...
Qualche idea?