Questions on OOP in MQL5 - page 90

 
Igor Makanu:

if in my example:

copy the asc and bid values in the onTick() method and use _Ask, _Bid (virtual trade) in the rest of the methods

will it be like working with global variables?

ZS: as an option, I can of course pass by reference &tick to all methods, but again questions which is more efficient

If this topic is still relevant, I would point out that the option to keep the fields is both less efficient and less correct conceptually. In principle, the two concepts almost always correlate.
Clean code (without side effects) is always better optimized by the compiler, and easier to understand.
If your object is meant to change its state under the influence of input data, it shouldn't store that input data (except for caching purposes).
You have to separate the flies from the cutlets.

 

Once asked a question about two ways to initialise variables in a class. This one:

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

And this one:

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

I asked what is the advantage of the second way and was told that you can initialize static members with it. But static members are not initialized that way.

So the question is the same - what is the difference in principle and what is the advantage of the second way?

 

Quote

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

Once asked a question about two ways to initialise variables in a class. Here's one like this:

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

Dmitry Fedoseev:

I asked what is the advantage of the second way and was told that static members can be initialized by it. But static members are not initialized that way.

They are constant fields, not static ones.

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

So the question is still the same - what is the difference in principle and what is the advantage of the second way?

If we discard the "it's considered bad form" statement, then whatever is more convenient, that's what we'll use, imho.

 
Yes, that's right, constant, confused)
 

I'll start the topic again, I deleted the previous post, I thought I figured it out on my own....


here is the code:

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;

I want to fill 3 enums and 2 int from privat section of CSetting with one int in which bit by bit I will store this data, sketched the code:

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;

in theory, it should work, I take the lower 2 + 3 +3 bits from the data for enum , and the remaining 24 bits from the int to fill param1 and param2, keeping the 12th bit as the character of the number


how do i check if there is an error ? )))

or would be thankful for someone else's ideas how to save this data to int

 
Alternatively: t+d*10+v*100
 
Igor Makanu:

how do you check if there are errors? )))

The usual way - pack it, unpack it, check if it's identical. preferably check all borderline cases.
 
Dmitry Fedoseev:
or t+d*10+v*100

this will not work,

you either have to shift bit by bit or multiply/split by 2, which is equivalent to shifting

TheXpert:
well, as usual - pack it, unpack it, check the identity. preferably check all borderline cases.

So, yes... logically

but i wasn't planning to do packing - i'm decreasing number of input variables for optimizer and i need many GA passes on top of them, so that GA does not converge quickly


boundary cases have already been checked, but from experience.... bugs are so crafty!!! )))

HH: I can of course reset the loop from 0...MAX_UINT into a file and look at it visually, but not the best option, imho.

 
Igor Makanu:

it won't work,

...

Why wouldn't it work? Three enumerations, none of them more than 10. Second grade primary schools arithmetic.

Reason: