Questions on OOP in MQL5 - page 82

 
Igor Makanu:

it does not matter what to initialize, even int - any number to call this constructor

and I chose 0.0 to avoid misprints - any digit, i.e. 0.0. It is harder to write and misprint than 123

(double)0

but not like that either)))) just now looked at the code normally, there is still a way to look at it abnormally))
 
Alexandr Andreev:

(double)0

no

I only write 0.0 - no other numbers are expected - there's not even a variable in the constructor

in general, as a fashionable author's style, probably not the best

 
Alexandr Andreev:

the point is not the x) but that there can be a float on the receiver, and it's not reliable to specify 0.0 either

0.0 is an unambiguous double for the compiler, float will be 0.f
 
Vladimir Simakov:
0.0 is unambiguous double to the compiler, float will be 0.f

credit)

 

While the "questions over 50" section is open, let me interject my own into the subject of casts.

- What are some ways to improve code in terms of fault tolerance or non-redundancy?

- IsCheckPointer()!=POINTER_INVALID check necessary? Or definitely not necessary? Explain why.

- Bringing to non-const, so that it's possible to call non-const methods. Can non-const methods be called directly in Compare method ? i.e. get rid of the yellow highlighted const ?

#include <ChartObjects\ChartObjectsShapes.mqh>

class CChartObjectRectangleX : public CChartObjectRectangle
  {
public:

   void CChartObjectRectangleX(){};      
   virtual int       Compare(const CObject *node,const int mode=0) const 
   {
   CChartObjectRectangleX *n=NULL;
   const CChartObjectRectangleX*nc=dynamic_cast<const CChartObjectRectangleX*>(node);
   if(nc!=NULL)
   n=(CChartObjectRectangleX *) nc;
   if(n!=NULL) {
     if(mode==0) return CompareDate(n); 
     if(mode==1) return CompareValue(n); }return 0;    }
 
   virtual int       CompareDate( CChartObjectRectangleX *node) const { 
   //if(node!=NULL) 
      return (this.Time(1)-node.Time(1)); return 0;    }
    virtual int       CompareValue( CChartObjectRectangleX *node) const { 
   //if(node!=NULL) 
      return ((this.Price(1)-node.Price(1))*10/Point()); return 0;    }
};
 
Aleksey Mavrin:

While the "questions over 50" section is open, let me interject my own into the subject of casts.

- What are some ways to improve code in terms of fault tolerance or non-redundancy?

- Is CheckPointer()!=POINTER_INVALID check necessary? Or definitely not necessary? Explain why.

- Bringing to non-const, so that it's possible to call non-const methods. Can non-const methods be called directly in the Compare method ? i.e. get rid of the yellow highlighted const ?

class CChartObjectRectangleX : public CChartObjectRectangle
  {
public:
   virtual int       Compare(const CObject *node,const int mode=0) const
   {
   const CChartObjectRectangleX *n=dynamic_cast<const CChartObjectRectangleX*>(node);
   return !n?0: mode==0?CompareDate(n):CompareValue(n);}
   
   virtual int CompareDate(const CChartObjectRectangleX *node) const {return !node?0:int(Time(1)-node.Time(1));}
   virtual int CompareValue(const CChartObjectRectangleX *node) const {return !node?0:(int)MathRound(((Price(1)-node.Price(1))*10/Point()));}
};

It's kind of the same as yours, only with less letters. It's a matter of taste, who likes it better, but I have removed extra variable (the compiler would probably remove it too within optimization framework).

Concerning my !node check. It must be replaced with CheckPointer(node)==POINTER_INVALID, but it is an overhead - a function call. Even if it's inlined, it's still at least dereferencing and checking the status flag. If only library or concrete, you've written program will use Compare methods, better !node and on code to watch for invalid pointer. If you too lazy to watch out for pointers or it's a library for underdogs, only CheckPointer(node)==POINTER_INVALID.

If you remove the const specifier you highlighted, you can't call these methods from a constant object.

UPD: the highlighted check can be removed, because it is in the called methods.

 
Aleksey Mavrin:

While the "questions over 50" section is open, let me interject my own into the subject of casts.

- What are some ways to improve code in terms of fault tolerance or non-redundancy?

- Is CheckPointer()!=POINTER_INVALID check necessary? Or definitely not necessary? Explain why.

- Bringing to non-const, so that it's possible to call non-const methods. Is it possible to call a non-const method directly in the Compare method ? i.e. to get rid of the yellow highlighted const ?

The idea is to write two methods of the same function with and without the const body - to put it mildly - not worth it))))

But the probability of encountering two methods is close to zero.... Because the possibility of existence ofCChartObjectRectangle::Price - without const in the body - I think it's unlikely.

The call of this function from outside has no effect. I.e. the const works only with internal functions and makes sure nothing was written into the object's memory (didn't change the variable's value). In other words, you cannot call Set(a) during const... Often, in some confusion, to make sure that this function does not overwrite anything, you can quickly arrange these consts (although this is probably my deletion).

Consider that the consts should be shoved just everywhere without getting)))) to make it easier to check something later.


Does CheckPointer()!=POINTER_INVALID need a check?

And why not.... make one bool Check(<template> &T) { retun CheckPointer(T)!=POINTER_INVALID } The compiler should make it as simple as possible. And it will look even better.

It's faster.

int a[1000];
for (int i=0; i<ArraySize(a); i++)....
или
for (int i=ArraySize(a); i>=0; i--)....
дак вот разницы не должно быть вообще


Well, I didn't change much.

template<typename T>
bool Check(T *a) {return CheckPointer(a)!=POINTER_INVALID;};

class CChartObjectRectangleX : public CChartObjectRectangle
  {
  #define  ME CChartObjectRectangleX
public:
   void ME(){};      
   virtual int       Compare(const CObject *node,const int mode=0) const 
   {
   const ME*nc=dynamic_cast<const ME*>(node);
   return Check(nc)?mode==0?CompareDate(nc):CompareValue(nc):0;
   } 
   virtual int       CompareDate(const ME *node) const            {return (this.Time(1)-node.Time(1));}
   virtual int       CompareValue(const ME *node) const           {return ((this.Price(1)-node.Price(1))*10/Point()); }
 #undef  ME
};

This is all your code.

 
Vladimir Simakov:

It seems to be the same as yours, only with fewer letters. So, it's a matter of taste, but I removed the extra variable (most likely, the compiler would have removed it as part of optimization).

Concerning my !node check. It must be replaced with CheckPointer(node)==POINTER_INVALID, but it is an overhead - a function call. Even if it's inlined, it's still at least dereferencing and checking the status flag. If only library or concrete, you've written program will use Compare methods, better !node and on code to watch for invalid pointer. If you too lazy to watch out for pointers or it's a library for underdogs, only CheckPointer(node)==POINTER_INVALID.

If you remove the const specifier, you can't call these methods from a constant object.

it took me a long time to open the tab


I guess 4 years of college didn't add much to my knowledge (explanation is lagging behind in the trash).

 

the variant without the constitution since the base class has no reference to input parameters will also work correctly, although this is not a very smart style

#include <ChartObjects\ChartObjectsShapes.mqh>

template<typename T>
bool Check(T *a) {return CheckPointer(a)!=POINTER_INVALID;};

class CChartObjectRectangleX : public CChartObjectRectangle
  { #define  ME CChartObjectRectangleX
public: 
   void ME(){};      
   virtual int       Compare(CObject *node,int mode=0) 
   {
   ME*nc=dynamic_cast<ME*>(node);
   return Check(nc)?mode==0?CompareDate(nc):CompareValue(nc):0;
   } 
   virtual int       CompareDate(ME *node)             {return (this.Time(1)-node.Time(1));}
   virtual int       CompareValue(ME *node)            {return ((this.Price(1)-node.Price(1))*10/Point()); }
 #undef  ME
};
 

Also a variant of the same code.

template<typename T>
bool Check(T *a) {return CheckPointer(a)!=POINTER_INVALID;};

class CChartObjectRectangleX : public CChartObjectRectangle
  { #define  ME CChartObjectRectangleX
public: 
   void ME(){};      
   virtual int       Compare(CObject *node,int mode=0)      {return Check(node)?mode==0?CompareDate(node):CompareValue(node):0;} 
   virtual int       CompareDate(CObject *node)             {return (  Time(1)-dynamic_cast<ME*>(node).Time(1));}
   virtual int       CompareValue(CObject *node)            {return ((Price(1)-dynamic_cast<ME*>(node).Price(1))*10/Point()); }
 #undef  ME
};


It's the same one with the consts.

template<typename T>
bool Check(T *a) {return CheckPointer(a)!=POINTER_INVALID;};

class CChartObjectRectangleX : public CChartObjectRectangle
  { #define  ME CChartObjectRectangleX
public: 
   void ME(){};      
   virtual int       Compare(CObject const *node,int const mode=0)   const{return Check(node)?mode==0?CompareDate(node):CompareValue(node):0;} 
   virtual int       CompareDate(CObject const *node)                const{return (  Time(1)-dynamic_cast<const ME*>(node).Time(1));}
   virtual int       CompareValue(CObject const *node)               const{return ((Price(1)-dynamic_cast<const ME*>(node).Price(1))*10/Point()); }
 #undef  ME
};
Reason: