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

 
Igor Makanu:

если я в моем примере:

в методе onTick() скопирую значения аск и бид и буду в остальных методах использовать _Ask, _Bid (виртуальная торговля)

то будет ли это аналогично работе с глобальными переменными? 

ЗЫ: как вариант, могу конечно передавать по ссылке &tick во все методы, но опять же вопросы, что эффективнее

Если эта тема ещё актуальна, то отмечу, что вариант с сохранением полей является и менее эффективным, и менее правильным концептуально.  В принципе эти 2 понятия почти всегда коррелируют.
Чистый код (без побочных эффектов) всегда лучше оптимизируется компилятором, и при этом легче для понимания.
Если ваш объект предназначен для изменения своего состояния под воздействием входных данных, то он не должен хранить в себе эти входные данные (за исключением целей кэширования).
Надо отделять мух от котлет.

 

Как-то задавал тут вопрос про два способа инициализации переменных в классе. Вот такой:

class CA{
   protected:
      int val;
   public:
      CA(){
         val=0;
      }      
};

И вот такой:

class CA{
   protected:
      int val;
   public:
      CA():val(0){
      }      
};

Поинтересовался, в чем преимущество второго способа и получил ответ, что им можно инициализировать статические члены. Но только не инициализируются статические члены таким образом. 

Так что вопрос все тот же - всем принципиальная разница и в чем преимущество второго способа?

 

Цита́та

Хочется закончить свою песнь важными словами. Любые описанные механизмы, принципы и паттерны, как и ООП в целом не стоит применять там, где это бессмысленно или может навредить. Это ведет к появлению статей со странными заголовками типа «Наследование — причина преждевременного старения» или «Синглтон может приводить к онкологическим заболеваниям».

 

 
Dmitry Fedoseev:

Как-то задавал тут вопрос про два способа инициализации переменных в классе. Вот такой:

https://www.mql5.com/ru/forum/85652/page45#comment_15975127

Dmitry Fedoseev:

Поинтересовался, в чем преимущество второго способа и получил ответ, что им можно инициализировать статические члены. Но только не инициализируются статические члены таким образом. 

не статические, а константные поля

class CA
{
protected:
   const int         val;
   static int        static_val;
public:
                     CA(): val(0) { }
};
static int CA::static_val = 12345;
Dmitry Fedoseev:

Так что вопрос все тот же - всем принципиальная разница и в чем преимущество второго способа?

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

 
Да, точно, константные, попутал)
 

апну еще раз топик, удалил прошлое сообщение думал разобрался сам....


есть такой код:

class CSetting  
{
public:
   enum T            {T1, T2, T3, T4, T5, T6, T7, T8};
   enum D            {D1, D2, D3, D4, D5, D6, D7, D8};
   enum V            {V1, V2, V3, v4};
private:
   int               param1, param2;
   T                 t;
   D                 d;
   V                 v;
public:
                     CSetting(const int in_param1,const int in_param2,const T in_t,const D in_d,const V in_v);
  };
//+------------------------------------------------------------------+
CSetting::CSetting(const int in_param1,const int in_param2,const T in_t,const D in_d,const V in_v)
   : param1(in_param1),
     param2(in_param2),
     t(in_t),
     d(in_d),
     v(in_v)
  {}

//--- input parameters
input int              Input_p1 = 1;   // p1 = -1000 ... +1000
input int              Input_p2 = 2;   // p2 = -1000 ... +1000
input CSetting::T      Input_T = CSetting::T::T1;
input CSetting::D      Input_D = CSetting::D::D1;
input CSetting::V      Input_V = CSetting::V::V1;

хочу 3 перечисления и 2 int из privat секции CSetting заполнять с помощью одного int в котором побитно буду хранить эти данные, набросал код:

class CSetting
  {
public:
   enum T            {T1, T2, T3, T4, T5, T6, T7, T8};
   enum D            {D1, D2, D3, D4, D5, D6, D7, D8};
   enum V            {V1, V2, V3, v4};
private:
   int               param1, param2;
   T                 t;
   D                 d;
   V                 v;
public:
                     CSetting(const uint data);
  };
//+------------------------------------------------------------------+
CSetting::CSetting(const uint data)
{
   v = (V)(data & 0x3);
   d = (D)((data >> 2) & 0x7);
   t = (T)((data >> 5) & 0x7);
   uint tmp = ((data >> 8) & 0xFFF);
   param2 = (tmp & 0x800) == 0x800 ? -(int)(tmp & 0x7FF) : (int)(tmp & 0x7FF);
   tmp = data >> 20;
   param1 = (tmp & 0x800) == 0x800 ? -(int)(tmp & 0x7FF) : (int)(tmp & 0x7FF);
}
//+------------------------------------------------------------------+
//--- input parameters
input int DATA         = 0xFFFFFFFF;

в теории это должно работать, беру младшие 2 + 3 +3 бита из data для enum , а оставшиеся 24 бит от int использую для заполнения param1 и param2 с сохранением в старшем 12-м бите знака числа


а как это проверить есть ли ошибки ? )))

ну или был бы благодарен за еще чей-нибудь вариант как сохранить в int эти данные

 
Можно и так: t+d*10+v*100
 
Igor Makanu:

а как это проверить есть ли ошибки ? )))

ну как обычно - запаковал, распаковал, проверил идентичность. желательно проверить все пограничные случаи.
 
Dmitry Fedoseev:
Можно и так: t+d*10+v*100

это не будет работать, 

нужно или сдвигать побитно или умножать/делить на 2, что эквивалентно сдвигу

TheXpert:
ну как обычно - запаковал, распаковал, проверил идентичность. желательно проверить все пограничные случаи.

так то да... логично

но не планировал упаковку делать - для оптимизатора уменьшаю количество input-переменных, да и кодом Грея сверху их, чтоб ГА быстро не сходилась - нужно много проходов ГА


граничные случаи уже проверял, но из опыта.... баги они такие коварные!!! )))

ЗЫ: могу конечно в файл цикл от 0...MAX_UINT сбросить, и посмотреть визуально, но не самый лучший вариант, имхо

 
Igor Makanu:

это не будет работать, 

...

С чего вдруг оно не будет работать? Три перечисления, ни одно из них не превышает 10. Арифметика начальной школы второго класса.