Вопросы по ООП в MQL5 - страница 67

 

такой еще вопрос, вот статья Вики Абстрактный класс

интересует пример С++

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;
  }

Результат работы программы:

Program:

This object of the class CB; call function cb.Abstr(); call function cb.fun().

This object of the class CC; call function cc.Abstr(); call function cc.fun().

.

.


интересует метод void fun ( void ) : 

- почему нет спецификатора virtual ?

- если добавить  virtual , что это изменит в дальнейшем ?


зачем и на кой это, вот код:

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

это работает как мне и хотелось бы - есть базовый класс и наследуюсь от него, но в наследниках нужен будет лишь один метод и хочу вне зависимости от очередности обьявления и инициализации, сначала вызывать обьекты у которых есть метод HighPriorityTask() и потом уже Task()


и естественно все в одном цикле

это возможно простыми способами?

 
Igor Makanu:

и естественно все в одном цикле

это возможно простыми способами?

А за каким таким хреном это нужно делать в одном цикле?

И почему это ещё и естественно?

Естественно циклов будет не меньше двух.

 
Koldun Zloy:

А за каким таким хреном это нужно делать в одном цикле?

И почему это ещё и естественно?

Естественно циклов будет не меньше двух.

ОК, 2 цикла, значит 2 цикла, значит чуда не будет ((

 
Igor Makanu:

ОК, 2 цикла, значит 2 цикла, значит чуда не будет ((

Можно попробовать вообще избавится от циклов.
Тут есть примеры как напечатать от 1 до 100 без цикла и без рекурсии.
Может эти примеры помогут, если конечно это вообще в тему вопроса ))

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

такой еще вопрос, вот статья Вики Абстрактный класс

интересует пример С++

Результат работы программы:

Program:

This object of the class CB; call function cb.Abstr(); call function cb.fun().

This object of the class CC; call function cc.Abstr(); call function cc.fun().

.

.


интересует метод void fun ( void ) : 

- почему нет спецификатора virtual ?

- если добавить  virtual , что это изменит в дальнейшем ?


зачем и на кой это, вот код:

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

это работает как мне и хотелось бы - есть базовый класс и наследуюсь от него, но в наследниках нужен будет лишь один метод и хочу вне зависимости от очередности обьявления и инициализации, сначала вызывать обьекты у которых есть метод HighPriorityTask() и потом уже Task()


и естественно все в одном цикле

это возможно простыми способами?

1. Если объявить указатель базового класса, и создать объект дочернего, то при вызове методов через этот самый указатель базового класса:

а) виртуальные методы вызываются дочернего класса (через специально создаваемую для этого таблицу виртуальных функций)

б) не-виртуальные методы вызываются базового класса. Даже если в дочернем классе они переопределены.

2. Если хочется прям в одном цикле, то

а) заморачивайтесь сортировкой массива объектов по типу.

б) для специфичных задач - держите отдельный массив указателей на объекты, эти задачи выполняющие. Т.е. все объекты, которые должны вызывать HighPriorityTask

должны храниться в отдельном массиве, вызываемом в первую очередь

з.ы. а как вообще вы теоретически могли представить без сортировки - что за один проход цикла, сначала выполниться то что есть у половины объектов, а потом остальные? :) Ну если только очереди заданий городить.

Но это уже творческий вопрос- можно дофига изысканных способов придумать решить копеечную задачу)) главное на законы физики не покушаться и всё будет хорошо)))

 
Aleksey Mavrin:

2. Если хочется прям в одном цикле, то

а) заморачивайтесь сортировкой массива объектов по типу.

б) для специфичных задач - держите отдельный массив указателей на объекты, эти задачи выполняющие. Т.е. все объекты, которые должны вызывать HighPriorityTask

должны храниться в отдельном массиве, вызываемом в первую очередь

з.ы. а как вообще вы теоретически могли представить без сортировки - что за один проход цикла, сначала выполниться то что есть у половины объектов, а потом остальные? :) Ну если только очереди заданий городить.

Но это уже творческий вопрос- можно дофига изысканных способов придумать решить копеечную задачу)) главное на законы физики не покушаться и всё будет хорошо)))

однозначно не хочется, думаю компилятор оптимизирует пустые методы

Aleksey Mavrin:

1. Если объявить указатель базового класса, и создать объект дочернего, то при вызове методов через этот самый указатель базового класса:

а) виртуальные методы вызываются дочернего класса (через специально создаваемую для этого таблицу виртуальных функций)

б) не-виртуальные методы вызываются базового класса. Даже если в дочернем классе они переопределены.

да, почему то не запомнил, что вот только правил библиотеку json https://www.mql5.com/en/code/11134   (где то на гитхабе чуть посвежее нашел чем в КБ)

там и были предупреждения компилятора 

deprecated behavior, hidden method calling will be disabled in a future MQL compiler version

лечится указанием метода в классе

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

спасибо, в общем понятная картина

 
Igor Makanu:

однозначно не хочется, думаю компилятор оптимизирует пустые методы

виртуальные? не факт. но вызов пустой функции вряд ли много ест в любом случае.

Igor Makanu:

ОК, 2 цикла, значит 2 цикла, значит чуда не будет ((

зачем пихать в один цикл то что по логике делается за два? ведь нет выигрыша ни по скорости, ни по наглядности, ни по простоте, а размеры винчестеров меряются давно не мегабайтами.

 
Andrei Trukhanovich:

зачем пихать в один цикл то что по логике делается за два? ведь нет выигрыша ни по скорости, ни по наглядности, ни по простоте, а размеры винчестеров меряются давно не мегабайтами.

а я и не пихал еще ничего! )))) 

пока только узнаю характеристики, чтобы сделать, что то похожее на нормальные вызовы методов

спасибо, в целом доходчиво разъяснили

Andrei Trukhanovich:

виртуальные? не факт.

примерчик бы, вопрос то и появился от большого выбора средств полиморфизма, то virtual то без него, то наследуем, то закрываем в производных классах этот метод

 
Roman:

Можно попробовать вообще избавится от циклов.
Тут есть примеры как напечатать от 1 до 100 без цикла и без рекурсии.
Может эти примеры помогут, если конечно это вообще в тему вопроса ))

А что? Еще один паттерн. Вот только что-то адепты паттернов его не признали, видимо не православный, не канонический.  Почему не реккурсия? Тоже реккурсия, только не вдоль, а поперек. 

Причина обращения: