Perguntas sobre OOP em MQL5 - página 67

 

Aqui está outra pergunta, aqui está o artigoWiki Abstract Class

Estou interessado em um exemplo em 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;
  }

O resultado do programa:

Programa:

Este objeto da classe CB; função de chamada cb.Abstr(); função de chamada cb.fun().

Este objeto da classe CC; função de chamada cc.Abstr(); função de chamada cc.fun().

.

.


interessado no método de diversão nula ( void ) :

- por que não há um especificador virtual?

- se acrescentarmos o virtual, o que mudará mais tarde?


por que e para que, aqui está o 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 eu quero - tenho uma classe base e herdei dela. Mas meus descendentes precisarão apenas de um método e quero chamar primeiro os objetos que têm o método HighPriorityTask() e depois Task(), independentemente da seqüência de declaração e inicialização


tudo em um loop

é possível fazer isso de uma maneira simples?

 
Igor Makanu:

e, é claro, tudo em um ciclo.

isso é possível por meios simples?

E por que diabos isso precisaria ser feito em um ciclo?

E por que também é natural?

Naturalmente, haverá pelo menos dois ciclos.

 
Koldun Zloy:

E por que diabos isso deveria ser feito no mesmo ciclo?

E por que também é natural?

Naturalmente, haverá pelo menos dois ciclos.

OK, dois ciclos significam dois ciclos, portanto nenhum milagre ((

 
Igor Makanu:

OK, 2 ciclos significa 2 ciclos, portanto nenhum milagre ((

Você poderia tentar se livrar completamente dos loops.
Há exemplos de como imprimir de 1 a 100 sem loops e sem repetição.
Talvez estes exemplos ajudem, se for mesmo relevante ))

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

Aqui está outra pergunta, aqui está o artigoWiki Abstract Class

Estou interessado em um exemplo em C++

O resultado do programa:

Programa:

Este objeto da classe CB; função de chamada cb.Abstr(); função de chamada cb.fun().

Este objeto da classe CC; função de chamada cc.Abstr(); função de chamada cc.fun().

.

.


interessado no método de diversão nula ( void ) :

- por que não há um especificador virtual?

- se acrescentarmos o virtual, o que mudará mais tarde?


por que e para que, aqui está o 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 eu quero - tenho uma classe base e herdei dela. Mas meus descendentes precisarão apenas de um método e quero chamar primeiro os objetos que têm o método HighPriorityTask() e depois Task(), independentemente da seqüência de declaração e inicialização


tudo em um loop

isso é possível usando um método simples?

1. Se você declarar um ponteiro de classe base e criar um objeto criança, então ao chamar métodos através deste mesmo ponteiro da classe base:

a) os métodos virtuais são chamados pela classe criança (através da tabela de funções virtuais especialmente criada para este fim)

b) os métodos não-virtuais são chamados por classe base. Mesmo que sejam anulados na classe infantil.

2. Se você quiser ter um único loop, então

a) Ordenar a matriz de objetos por tipo.

b) Para cada tarefa específica, mantenha um conjunto separado de ponteiros para objetos que resolvam essas tarefas. Isto é, todos os objetos que devem chamarHighPriorityTask

devem ser armazenados em uma matriz separada, que deve ser chamada primeiro.

h.e. Como você poderia imaginar que em geral, sem classificar, a metade dos objetos será executada primeiro, e depois o resto? :) Bem, nem que seja para começar uma fila de trabalho.

Mas esta é uma questão criativa, você pode inventar muitas maneiras sofisticadas de resolver um problema de centavo))))) O principal é não invadir as leis da física e tudo ficará bem))))

 
Aleksey Mavrin:

2. Se você quiser usar o mesmo laço, então

a) Classificar o conjunto de objetos por tipo.

b) Para tarefas específicas, mantenha um conjunto separado de indicadores para os objetos que realizam essas tarefas. Isto é, todos os objetos que devem chamarHighPriorityTask

devem ser armazenados em uma matriz separada, que deve ser chamada primeiro.

h.e. Como você poderia imaginar que em geral, sem classificar, a metade dos objetos será executada primeiro, e depois o resto? :) Bem, nem que seja para começar uma fila de trabalho.

Mas esta é uma questão criativa, você pode encontrar muitas maneiras sofisticadas de resolver uma tarefa de um centavo))))) O principal é não invadir as leis da física, e tudo ficará bem))))

Eu não quero, acredito que o compilador otimizará os métodos vazios.

Aleksey Mavrin:

1. Se você declarar um ponteiro de uma classe base e criar um objeto criança, então ao chamar métodos através deste mesmo ponteiro da classe base

a) os métodos virtuais são chamados pela classe criança (através da tabela de funções virtuais especialmente criada para este fim)

b) os métodos não-virtuais são chamados por classe base. Mesmo que sejam anulados na classe infantil.

Sim, não lembro que acabei de consertar a biblioteca jsonhttps://www.mql5.com/en/code/11134(encontrei-a em um githab em algum lugar um pouco mais fresco do que o KB).

e havia avisos de compilação

comportamento depreciado, chamada de método oculto será desativada em uma futura versão do compilador MQL

fixado através da especificação de um método em uma classe

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

Obrigado, é uma imagem bastante clara

 
Igor Makanu:

definitivamente não quero, eu acho que o compilador otimizará métodos vazios

Mas chamar uma função vazia não deve comer muito de qualquer maneira.

Igor Makanu:

OK, 2 loops significa 2 loops, então não haverá milagre ((

Por que eu deveria enfiar em um loop algo que é logicamente feito em dois loops? Porque não há ganho de velocidade, clareza e simplicidade e o tamanho dos discos rígidos não é medido em megabytes há muito tempo.

 
Andrei Trukhanovich:

Por que encher em um ciclo o que logicamente pode ser feito em dois? Porque não há ganho em velocidade, clareza ou simplicidade e o tamanho dos discos rígidos não é medido em megabytes.

Eu ainda nem sequer as usei! ))))

só precisa conhecer as especificações para fazer algo semelhante às chamadas do método normal

Obrigado. Isso o explica muito bem.

Andrei Trukhanovich:

Virtual? Não necessariamente.

Gostaria de mostrar um exemplo, a questão surgiu por causa da grande escolha de meios de polimorfismo, seja virtual ou sem ele, ou herdar ou fechar este método em classes derivadas

 
Roman:

Você pode tentar se livrar completamente dos loops.
Há exemplos de como imprimir de 1 a 100 sem loops e sem repetição.
Talvez estes exemplos ajudem, se for mesmo relevante ))

Por quê? Outro padrão. A única coisa que os adeptos do padrão não reconheceram, evidentemente não é ortodoxo e canônico. Por que não a recorrência? Também recorrência, apenas não ao longo, mas transversalmente.

Razão: