Domande su OOP in MQL5 - pagina 67

 

Ecco un'altra domanda, ecco l'articolo diWiki Abstract Class

Sono interessato a un esempio C++

class CA { // Абстрактный класс
  public:
    CA ( void ) { std::cout << "This object of the class "; }

    virtual void Abstr ( void ) = 0; // Чистая (пустая) виртуальная функция.
    void         fun   ( void ) { std::cout << "Реализация не будет наследоваться!"; }

    ~CA () { std::cout << "." << std::endl; } //Вызывается в обр. порядке конструкторов
  };

class CB : public CA {
  public:
    CB ( void ) { std::cout << "CB;"; }

    void Abstr ( void ){ std::cout << " call function cb.Abstr();"; } //Подменяющая функция.
    void fun   ( void ){ std::cout << " call function cb.fun()"; }

    ~CB () {} // Неверно для абстр. кл. ~CB(){ ~CA(); } 
  };

class CC : public CA {
  public:
    CC ( void ) { std::cout << "CC;"; }

    void Abstr ( void) { std::cout << " call function cc.Abstr();"; } //Подменяющая функция.
    void fun   ( void ) { std::cout << " call function cc.fun()"; }

  ~CC () {} // Неверно для абстр. кл. ~CC(){ ~CA(); } 
  };

int main () {
  std::cout << "Program:" << std::endl;
  CB cb;
  cb.Abstr(); cb.fun(); cb.~CB();

  CC cc;
  cc.Abstr(); cc.fun(); cc.~CC();

  return 0;
  }

Il risultato del programma:

Programma:

Questo oggetto della classe CB; chiama la funzione cb.Abstr(); chiama la funzione cb.fun().

Questo oggetto della classe CC; chiama la funzione cc.Abstr(); chiama la funzione cc.fun().

.

.


interessato al metodo void fun ( void ):

- perché non c'è uno specificatore virtuale?

- Se aggiungiamo il virtuale, cosa cambierà in seguito?


perché e per cosa, ecco il codice:

class base
{
public:
   virtual void HighPriorityTask() {}
   virtual void Task() {}
};
//+------------------------------------------------------------------+
class A: public base
{
public:
   virtual void HighPriorityTask() { Print(__FUNCSIG__); }
};
//+------------------------------------------------------------------+
class B: public base
{
public:
   virtual void Task() { Print(__FUNCSIG__); }
};

//+------------------------------------------------------------------+
void OnStart()
{
   base *obj[4];;
   obj[0] = new A; obj[1] = new A;  
   obj[2] = new B; obj[3] = new B; 
   for(int i=ArraySize(obj)-1; i>=0; i--)
   {
      obj[i].HighPriorityTask();
      obj[i].Task();
   }
   
   for(int i=ArraySize(obj)-1; i>=0; i--)
      delete obj[i];

2020.05.28 14:41:20.294 tst (EURUSD,H1) void B::Task()

2020.05.28 14:41:20.298 tst (EURUSD,H1) void B::Task()

2020.05.28 14:41:20.298 tst (EURUSD,H1) void A::HighPriorityTask()

2020.05.28 14:41:20.298 tst (EURUSD,H1) void A::HighPriorityTask()

funziona nel modo in cui voglio - ho una classe base ed eredito da essa. Ma i miei discendenti avranno bisogno di un solo metodo e voglio chiamare gli oggetti che hanno il metodo HighPriorityTask() prima e poi Task() indipendentemente dalla sequenza di dichiarazione e inizializzazione


tutto in un ciclo

è possibile farlo in modo semplice?

 
Igor Makanu:

e naturalmente tutto in un solo ciclo.

è possibile con mezzi semplici?

E perché cazzo dovrebbe essere fatto in un solo ciclo?

E perché è anche naturale?

Naturalmente ci saranno almeno due cicli.

 
Koldun Zloy:

E perché cazzo dovrebbe essere fatto nello stesso ciclo?

E perché è anche naturale?

Naturalmente ci saranno almeno due cicli.

OK, due cicli significa due cicli, quindi nessun miracolo ((

 
Igor Makanu:

OK, 2 cicli significa 2 cicli, quindi nessun miracolo ((

Si potrebbe provare a sbarazzarsi del tutto dei loop.
Ci sono esempi di come stampare da 1 a 100 senza loop e senza ricorsione.
Forse questi esempi aiuteranno, se è pertinente ))

Печать от 1 до 100 на C ++, без цикла и рекурсии | Портал информатики для гиков
  • 2020.01.01
  • espressocode.top
Ниже приводится программа на C ++, которая печатает от 1 до 100 без цикла и без рекурсии. #include using namespace std;    template
 
Roman:
Qual è il senso di questa assurdità?
 
Igor Makanu:

Ecco un'altra domanda, ecco l'articolo diWiki Abstract Class

Sono interessato a un esempio C++

Il risultato del programma:

Programma:

Questo oggetto della classe CB; chiama la funzione cb.Abstr(); chiama la funzione cb.fun().

Questo oggetto della classe CC; chiama la funzione cc.Abstr(); chiama la funzione cc.fun().

.

.


interessato al metodo void fun ( void ):

- perché non c'è uno specificatore virtuale?

- Se aggiungiamo il virtuale, cosa cambierà in seguito?


perché e per cosa, ecco il codice:

2020.05.28 14:41:20.294 tst (EURUSD,H1) void B::Task()

2020.05.28 14:41:20.298 tst (EURUSD,H1) void B::Task()

2020.05.28 14:41:20.298 tst (EURUSD,H1) void A::HighPriorityTask()

2020.05.28 14:41:20.298 tst (EURUSD,H1) void A::HighPriorityTask()

funziona nel modo in cui voglio - ho una classe base ed eredito da essa. Ma i miei discendenti avranno bisogno di un solo metodo e voglio chiamare gli oggetti che hanno il metodo HighPriorityTask() prima e poi Task() indipendentemente dalla sequenza di dichiarazione e inizializzazione


tutto in un ciclo

è possibile farlo in modo semplice?

1. Se dichiarate un puntatore alla classe base e create un oggetto figlio, allora quando chiamate i metodi tramite questo stesso puntatore della classe base:

a) i metodi virtuali sono chiamati dalla classe figlia (tramite la tabella delle funzioni virtuali creata appositamente per questo scopo)

b) i metodi non virtuali sono chiamati dalla classe base. Anche se sono sovrascritti nella classe figlio.

2. Se volete avere un solo ciclo, allora

a) Ordina l'array di oggetti per tipo.

b) Per ogni compito specifico, mantenere un array separato di puntatori agli oggetti che risolvono questi compiti. Cioè tutti gli oggetti che devono chiamareHighPriorityTask

dovrebbe essere memorizzato in un array separato, che dovrebbe essere chiamato per primo.

h.e. Come potete immaginare che in generale, senza ordinamento, la metà degli oggetti sarà eseguita per prima, e poi il resto? :) Beh, se non altro per iniziare una coda di lavoro.

Ma questa è una domanda creativa, si possono inventare un sacco di modi sofisticati per risolvere un problema da un centesimo))) L'importante è non invadere le leggi della fisica e tutto andrà bene)))

 
Aleksey Mavrin:

2. Se volete usare lo stesso ciclo, allora

a) Ordina l'array di oggetti per tipo.

b) Per compiti specifici, tenete un array separato di puntatori a oggetti che eseguono questi compiti. Cioè tutti gli oggetti che devono chiamareHighPriorityTask

dovrebbe essere memorizzato in un array separato, che dovrebbe essere chiamato per primo.

h.e. Come potete immaginare che in generale, senza ordinamento, la metà di tutti gli oggetti sarà eseguita per prima, e poi il resto? :) Beh, se non altro per iniziare una coda di lavoro.

Ma questa è una domanda creativa, si possono inventare un sacco di modi sofisticati per risolvere un compito da un centesimo))) La cosa principale è non violare le leggi della fisica, e tutto andrà bene)))

Non voglio, credo che il compilatore ottimizzerà i metodi vuoti.

Aleksey Mavrin:

1. Se dichiarate un puntatore di una classe base e create un oggetto figlio, allora quando chiamate metodi tramite questo puntatore della classe base

a) i metodi virtuali sono chiamati dalla classe figlia (tramite la tabella delle funzioni virtuali creata appositamente per questo scopo)

b) i metodi non virtuali sono chiamati dalla classe base. Anche se sono sovrascritti nella classe figlio.

sì, non ricordo che ho appena sistemato la libreria jsonhttps://www.mql5.com/en/code/11134(l'ho trovata su un githab da qualche parte un po' più fresca della KB).

e c'erano avvertimenti del compilatore

comportamento deprecato, la chiamata al metodo nascosto sarà disabilitata in una futura versione del compilatore MQL

fissato specificando un metodo in una classe

this.JSONValue:: getLong(getValue(index),out);

Grazie, è un'immagine abbastanza chiara

 
Igor Makanu:

sicuramente non voglio, penso che il compilatore ottimizzerà i metodi vuoti

Ma chiamando una funzione vuota non è probabile che si mangi molto comunque.

Igor Makanu:

OK, 2 loop significa 2 loop, quindi non ci sarà nessun miracolo ((

Perché dovrei infilare in un solo ciclo qualcosa che logicamente si fa in due cicli? Perché non c'è nessun guadagno in velocità, chiarezza e semplicità, mentre la dimensione degli hard disk è stata a lungo misurata non in megabyte.

 
Andrei Trukhanovich:

Perché stipare in un solo ciclo ciò che può essere logicamente fatto in due? Non c'è guadagno in velocità, chiarezza o semplicità, e la dimensione dei dischi rigidi non si misura in megabyte.

Non li ho ancora usati! ))))

basta conoscere le specifiche per fare qualcosa di simile alle normali chiamate di metodo

Grazie, questo spiega molto bene.

Andrei Trukhanovich:

Virtuale? Non necessariamente.

Vorrei potervi mostrare un esempio, la questione è sorta a causa della grande scelta di mezzi di polimorfismo, o virtuale o senza, o ereditare o chiudere questo metodo nelle classi derivate

 
Roman:

Puoi provare a sbarazzarti del tutto dei loop.
Ci sono esempi di come stampare da 1 a 100 senza loop e senza ricorsione.
Forse questi esempi aiuteranno, se è pertinente ))

Perché? Un altro modello. L'unica cosa che gli adepti del pattern non hanno riconosciuto, evidentemente non è ortodosso e canonico. Perché non la ricorsione? Anche la ricorsione, solo non lungo, ma attraverso.

Motivazione: