OLP. Problemi di applicazione - pagina 11

 
Interesting:

Quanto è bello poter leggere... :)

Anche l'approccio non è male, anche se come ho capito entrambi questi approcci sono calcolati sul trasferimento/lettura di un solo parametro (anche se di tipo diverso).

Ma come risolvere il problema, quando hai molti parametri e non puoi metterli tutti in una classe base?

Per quanto ho capito, devi inserire un indice del parametro che stai passando (puoi anche creare un array in una classe con parametri memorizzati per indice)?

Non lo capisco nemmeno io...

Nel mio esempio c'è un indice, solo che non è numerico in forma esplicita, ma un enum....

 

Lascia perdere, non ne vale la pena.

 

Interesting:

Yedelkin:

In generale, dopo una discussione sul problemahttps://www.mql5.com/ru/forum/3566/page6#comment_58280 ha inviato una domanda alla SR.

1. Non lo so, non lo so.

Non credo che gli sviluppatori faranno certi passi, sacrificando la funzionalità in nome della sicurezza (e giustamente da un lato).

Riferendo.

L'applicazione era così:
...

Suggerimento:

1. Chiarire la sezione "Polimorfismo" nel manuale "Polimorfismo" in termini di specificare come riempire correttamente le forme di array[10] con istanze di classi derivate da CShape (fare un esempio).

2. controllare se la stringa è scritta correttamente:

CShape[10] shapes;                       // массив объектов CShape

3. Spiegare se mettere o meno le parentesi graffe subito dopo il nome della classe dichiarata quando si dichiarano le classi:

classe CShape{};

classe CCircle{} :public CShape

classe CSquare{} :public CShape

Risposta:

Rashid Umarov 2011.04.11 15:17

Al momento di scrivere la guida, alcuni punti non erano ancora chiari per la documentazione. Correggeremo questo punto e aggiungeremo il codice corretto. Grazie per il suo messaggio.

Una descrizione estesa sarà aggiunta all'Aiuto, eccone un estratto:

Supponiamo che il nostro programma usi oggetti di tipo diverso (CCircle e CSquare) ma ereditati da un tipo base CShape. Il polimorfismo ci permette di creare un array di oggetti di tipo base CShape, ma quando dichiariamo questo array, gli oggetti stessi sono ancora sconosciuti e il loro tipo è indefinito.

La decisione di quale tipo di oggetto sarà contenuto in ogni elemento dell'array sarà presa durante l'esecuzione del programma. Questo implica la creazione dinamica di oggetti per le classi corrispondenti e, quindi, la necessità di usare puntatori di oggetti invece degli oggetti stessi.

Per creare oggetti dinamicamente, si usa l'operatore new; ogni oggetto di questo tipo deve essere cancellato indipendentemente ed esplicitamente dall'operatore delete. Pertanto, dichiareremo un array di puntatori di tipo CShape e creeremo un oggetto del tipo richiesto per ciascuno dei suoi elementi(new_class_name), come è mostrato nello script di esempio:

//+------------------------------------------------------------------+

//| Script program start function                                    |

//+------------------------------------------------------------------+

void OnStart()

  {

//--- объявим массив указателей объектов базового типа 

   CShape *shapes[5];   // массив указателей на объекты CShape



//--- здесь заполняем массив производными объектами

//--- объявим указатель на объект типа CCircle

   CCircle *circle=new CCircle();

//--- задаем свойства объекта по указателю circle

   circle.SetRadius(2.5);

//--- поместим в shapes[0] значение указателя

   shapes[0]=circle;



//--- создаем еще один объект CCircle и запишем его указатель в shapes[1]

   circle=new CCircle();

   shapes[1]=circle;

   circle.SetRadius(5);



//--- тут мы намеренно "забыли" задать значение для shapes[2]

//circle=new CCircle();

//circle.SetRadius(10);

//shapes[2]=circle;



//--- для неиспользуемого элемента установим значение NULL

   shapes[2]=NULL;



//--- создаем объект CSquare и запишем его указатель в shapes[3]

   CSquare *square=new CSquare();

   square.SetSide(5);

   shapes[3]=square;



//--- создаем объект CSquare и запишем его указатель в shapes[4]

   square=new CSquare();

   square.SetSide(10);

   shapes[4]=square;



//--- массив указателей есть, получим его размер

   int total=ArraySize(shapes);

//--- пройдем в цикле по всем указателям в массиве 

   for(int i=0; i<5;i++)

     {

      //--- если по указанному индексу указатель является валидным

      if(CheckPointer(shapes[i])!=POINTER_INVALID)

        {

         //--- выведем в лог тип и площадь фигуры

         PrintFormat("Объект типа %d имеет площадь %G",

               shapes[i].GetType(),

               shapes[i].GetArea());

        }

      //--- если указатель имеет тип POINTER_INVALID

      else

        {

         //--- сообщим об ошибке

         PrintFormat("Объект shapes[%d] не инициализирован! Его указатель %s",

                     i,EnumToString(CheckPointer(shapes[i])));

        }

     }



//--- мы должны самостоятельно уничтожить все созданные динамические объекты

   for(int i=0;i<total;i++)

     {

      //--- удалять можно только объекты, чей указатель имеет тип POINTER_DYNAMIC

      if(CheckPointer(shapes[i])==POINTER_DYNAMIC)

        {

         //--- сообщим об удалении

         PrintFormat("Удаляем shapes[%d]",i);

         //--- уничтожим объект по его указателю

         delete shapes[i];

        }

     }

  }


Notate che quando cancellate un oggetto con l'operatore delete, dovreste controllare il tipo del suo puntatore. Potete cancellare solo oggetti con puntatore POINTER_DYNAMIC, otterrete un errore per puntatori di altro tipo.

Penso che questo esempio copra completamente l'idea di creare un array di puntatori.
Rashid Umarov 2011.04.11 10:31

Grazie per il post, abbiamo corretto №2 e №3. Sarà nelle nuove versioni di aiuto



 

Domanda. La libreria standard usa le seguenti linee

void CTrade::Request(MqlTradeRequest& request) const
  {...}

Il manuale di riferimento dice: " lo specificatore const non è applicabile ai membri di strutture e classi". Cosa significa usare const in un metodo di classe sopra e quali sono le regole per usarlo in questi casi?

Документация по MQL5: Стандартная библиотека
Документация по MQL5: Стандартная библиотека
  • www.mql5.com
Стандартная библиотека - Документация по MQL5
 

Yedelkin:

...............

Cosa significa l'uso di const in un metodo di classe e quali sono le regole per usarlo in questi casi?

Oh sì, anche io me lo sono chiesto per molto tempo. Voglio usare la lingua in modo significativo, pienamente consapevole delle "regole del gioco".
 
Yedelkin:

Domanda. La libreria standard usa le seguenti linee

Il manuale di riferimento dice: " lo specificatore const non è applicabile ai membri di strutture e classi". Cosa significa usare const in un metodo di classe sopra e quali sono le regole per usarlo in questi casi?

Un membro di una struttura/classe è una cosa, ma un metodo è un'altra.

Un metodo descritto come const significa che non cambia lo stato/membri della sua classe. Cioè, dopo aver chiamato un tale metodo, lo stato interno della classe rimane invariato. Si usa per dire in aggiunta al compilatore di controllare i tentativi di cambiare i membri della classe.

 
Renat:

Unmembro di una struttura/classe è una cosa e un metodo è un'altra.

Un metodo descritto come const significa che non cambia lo stato/membri della sua classe. Cioè, lo stato interno della classe rimane invariato dopo la chiamata di questo metodo. Si usa per dire in aggiunta al compilatore di controllare i tentativi di cambiare i membri della classe.

Wow. Grazie! E mi sono scervellato.

 
TheXpert:
A proposito, una domanda logica mentre siamo sull'argomento: non c'è un manuale e non è previsto?

Come potrebbe essere usato? Perché i fili non interagiscono tra loro,

Se i dati potessero essere trasferiti liberamente tra i thread, allora sì, ci sarebbe bisogno di una tale istruzione.

 
Accidenti, pensavo di scrivere qualcosa di sbagliato :) ora so cos'è. Non volatile, ovviamente, ma mutabile:))
 
class COracleTemplate
  {
private:
public:
   string            filename;
                     COracleTemplate(){Init();};
                    ~COracleTemplate(){DeInit();};
   virtual void      Init(){filename=this.Name();Print("loadSettings from ",filename);};
   virtual void      DeInit(){Print("saveSettings to ",filename);};
   virtual string    Name(){return("Prpototype");};
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CCO2:public COracleTemplate
  {
   virtual string    Name(){return("CO2");};
  };
class CH2O:public COracleTemplate
  {
   virtual string    Name(){return("H2O");};
  };
COracleTemplate* CO2,*H2O;
void OnStart()
  {
   CO2=new CCO2;
   Print(CO2.Name()," filename=",CO2.filename);
   delete CO2;
   
   H2O=new CH2O;
   Print(H2O.Name()," filename=",H2O.filename);
   delete H2O;
   
  }

Buon pomeriggio.

Una tale domanda.

Sul codice sopra

Cosa ho fatto di sbagliato o è generalmente irraggiungibile in MT5?

Voglio (come penso sia ovvio) - ottenere nomi sovrascritti in variabili di nomi di file...