Preguntas sobre POO en MQL5 - página 67

 

Aquí hay otra pregunta, aquí está el artículo dela Wiki Abstract Class

Estoy interesado en un ejemplo de 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;
  }

El resultado del programa:

Programa:

Este objeto de la clase CB; llama a la función cb.Abstr(); llama a la función cb.fun().

Este objeto de la clase CC; llama a la función cc.Abstr(); llama a la función cc.fun().

.

.


interesado en el método void fun ( void ) :

- ¿por qué no hay un especificador virtual?

- si añadimos lo virtual, ¿qué cambiará después?


por qué y para qué, aquí está el código:

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()

funciona como yo quiero - tengo una clase base y heredo de ella. Pero mis descendientes sólo necesitarán un método y quiero llamar primero a los objetos que tienen el método HighPriorityTask() y luego a Task() independientemente de la secuencia de declaración e inicialización


todo en un bucle

¿es posible hacerlo de forma sencilla?

 
Igor Makanu:

y, por supuesto, todo en un solo ciclo.

¿es posible por medios sencillos?

¿Y por qué cojones hay que hacerlo en un solo ciclo?

¿Y por qué es también natural?

Naturalmente, habrá al menos dos ciclos.

 
Koldun Zloy:

¿Y por qué carajo se debe hacer en el mismo ciclo?

¿Y por qué es también natural?

Naturalmente, habrá al menos dos ciclos.

OK, dos ciclos significa dos ciclos, así que no hay milagro ((

 
Igor Makanu:

OK, 2 ciclos significa 2 ciclos, así que no hay milagro ((

Podrías intentar deshacerte de los bucles por completo.
Hay ejemplos de cómo imprimir de 1 a 100 sin bucles y sin recursividad.
Tal vez estos ejemplos le ayuden, si es que son relevantes ))

Печать от 1 до 100 на C ++, без цикла и рекурсии | Портал информатики для гиков
  • 2020.01.01
  • espressocode.top
Ниже приводится программа на C ++, которая печатает от 1 до 100 без цикла и без рекурсии. #include using namespace std;    template
 
Roman:
¿Qué sentido tiene esta tontería?
 
Igor Makanu:

Aquí hay otra pregunta, aquí está el artículo dela Wiki Abstract Class

Estoy interesado en un ejemplo de C++

El resultado del programa:

Programa:

Este objeto de la clase CB; llama a la función cb.Abstr(); llama a la función cb.fun().

Este objeto de la clase CC; llama a la función cc.Abstr(); llama a la función cc.fun().

.

.


interesado en el método void fun ( void ) :

- ¿por qué no hay un especificador virtual?

- si añadimos lo virtual, ¿qué cambiará después?


por qué y para qué, aquí está el código:

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()

funciona como yo quiero - tengo una clase base y heredo de ella. Pero mis descendientes sólo necesitarán un método y quiero llamar primero a los objetos que tienen el método HighPriorityTask() y luego a Task() independientemente de la secuencia de declaración e inicialización


todo en un bucle

¿es posible con un método sencillo?

1. Si declaras un puntero de la clase base y creas un objeto hijo, entonces al llamar a los métodos a través de este mismo puntero de la clase base:

a) los métodos virtuales son llamados por la clase hija (a través de la tabla de funciones virtuales especialmente creada para ello)

b) los métodos no virtuales son llamados por la clase base. Incluso si se anulan en la clase hija.

2. Si quieres tener un solo bucle, entonces

a) Ordenar la matriz de objetos por tipo.

b) Para cada tarea específica, mantenga una matriz separada de punteros a los objetos que resuelven estas tareas. Es decir, todos los objetos que deben llamar aHighPriorityTask

debe ser almacenado en un array separado, que debe ser llamado primero.

h.e. ¿Cómo puede imaginarse que, en general, sin clasificación, la mitad de los objetos se ejecutarán primero y luego el resto? :) Bueno, aunque sólo sea para iniciar una cola de trabajo.

Pero esta es una pregunta creativa, se pueden idear un montón de formas sofisticadas para resolver un problema de centavos))) Lo principal es no invadir las leyes de la física y todo estará bien)))

 
Aleksey Mavrin:

2. Si quieres utilizar el mismo bucle, entonces

a) Ordena la matriz de objetos por tipo.

b) Para las tareas específicas, mantener una matriz separada de punteros a los objetos que realizan estas tareas. Es decir, todos los objetos que deben llamar aHighPriorityTask

debe almacenarse en una matriz separada, que debe llamarse primero.

h.e. ¿Cómo puede imaginarse que, en general, sin clasificación, la mitad de los objetos se ejecutarán primero y luego el resto? :) Bueno, aunque sólo sea para iniciar una cola de trabajo.

Pero esta es una pregunta creativa, se puede llegar a un montón de maneras sofisticadas para resolver una tarea de un centavo))) Lo principal es no invadir las leyes de la física, y todo estará bien)))

No quiero, creo que el compilador optimizará los métodos vacíos.

Aleksey Mavrin:

1. Si declaras un puntero de una clase base y creas un objeto hijo, entonces al llamar a los métodos a través de este mismo puntero de la clase base

a) los métodos virtuales son llamados por la clase hija (a través de la tabla de funciones virtuales especialmente creada para ello)

b) los métodos no virtuales son llamados por la clase base. Incluso si se anulan en la clase hija.

sí, no recuerdo que acabo de arreglar la biblioteca jsonhttps://www.mql5.com/en/code/11134(lo encontré en un githab en algún lugar un poco más fresco que la KB).

y había advertencias del compilador

comportamiento obsoleto, la llamada a métodos ocultos se desactivará en una futura versión del compilador MQL

se fija especificando un método en una clase

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

Gracias, es una imagen bastante clara

 
Igor Makanu:

definitivamente no quiero, creo que el compilador optimizará los métodos vacíos

Pero llamar a una función vacía no es probable que coma mucho de todos modos.

Igor Makanu:

OK, 2 bucles significa 2 bucles, así que no habrá milagro ((

¿Por qué debería meter en un solo bucle algo que lógicamente se hace en dos? Porque no se gana en velocidad, claridad y simplicidad, y el tamaño de los discos duros no se mide en megabytes hace tiempo.

 
Andrei Trukhanovich:

¿Por qué meter en un ciclo lo que lógicamente se puede hacer en dos? No se gana en velocidad, claridad o sencillez, y el tamaño de los discos duros no se mide en megabytes.

Todavía no los he usado. ))))

sólo hay que conocer las especificaciones para hacer algo similar a las llamadas a métodos normales

Gracias. Eso lo explica muy bien.

Andrei Trukhanovich:

¿Virtual? No necesariamente.

Me gustaría poder mostrarte un ejemplo, la pregunta surgió por la gran elección de medios de polimorfismo, ya sea virtual o sin él, o heredar o cerrar este método en las clases derivadas

 
Roman:

Puedes intentar deshacerte de los bucles por completo.
Hay ejemplos de cómo imprimir de 1 a 100 sin bucles y sin recursividad.
Tal vez estos ejemplos le ayuden, si es que es relevante ))

¿Por qué? Otro patrón. Lo único es que los adeptos al patrón no lo reconocieron, evidentemente no es ortodoxo y canónico. ¿Por qué no la recursión? También la recursión, sólo que no a lo largo, sino a lo ancho.