Deprecated behavior - why?

Doerk Hilger  

Hi,

I am not able to solve this. The basic idea is this code, but it produces the warning message for line 31. 

#include <Charts\Chart.mqh>

//+------------------------------------------------------------------+
//| CChartExt class                                                  |
//+------------------------------------------------------------------+
class CChartExt : public CChart
   {
      protected:
         int         m_subwin;
      public:
         CChartExt()       { Attach(); }
        ~CChartExt(void)   { Detach(); }
            
      public:
//+------------------------------------------------------------------+
//| Attaching chart                                                  |
//+------------------------------------------------------------------+         
         void        Attach(void)         { Attach(::ChartID()); } 
         void        Attach(const long chart)   
            { 
               CChart::Attach(chart);
               if (m_chart_id==::ChartID())
                  m_subwin=MathMax(0,::ChartWindowFind());
               else
                  m_subwin=0;
            }               
         void        Detach(void)                     { m_subwin=-1; CChart::Detach(); }
         int         SubWindow(void)                  { return m_subwin; }
         int         Width(void)                      { return WidthInPixels(); }
         int         Height(void)                     { return HeightInPixels(m_subwin); }
         int         SubwindowY(void)                 { return SubwindowY(m_subwin); }                  // <---- Warning message 

   };

CChartExt __Chart;
   
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   int yoff=__Chart.SubwindowY(0);                                                                      // <---- Warning message
   return INIT_SUCCEEDED;
  }


After changing line 31, which isn´t understandable why, to this

         int         SubwindowY(void)                 { return CChart::SubwindowY(m_subwin); }

I still get the warning message at the second position. 

Is the compiler correct here or am I totally wrong?

Thanks in advance 

lippmaje  

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

The extension class does not properly override the base class method.

A fix to this could be:

int         SubwindowY(int subwin=-1)        { return CChart::SubwindowY(subwin<0 ? m_subwin : subwin); }
Doerk Hilger  
lippmaje:

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

The extension class does not properly override the base class method.

A fix to this could be:

Yes, that helps, thanx. But imo this is not correct, because I do not overwrite the base function at all. The base function has int-parameter, the function in the derived class has no parameters, just the same name. 

Anyway, here is another example, which is also not working:


#include <Charts\Chart.mqh>

//+------------------------------------------------------------------+
//| CChartExt class                                                  |
//+------------------------------------------------------------------+
class CChartExt : public CChart
   {
      protected:
         int         m_subwin;
      public:
         CChartExt()       { Attach(); }
        ~CChartExt(void)   { Detach(); }
            
      public:
//+------------------------------------------------------------------+
//| Attaching chart                                                  |
//+------------------------------------------------------------------+         
         void        Attach(void)         { Attach(::ChartID()); } 
         void        Attach(const long chart)   
            { 
               CChart::Attach(chart);
               if (m_chart_id==::ChartID())
                  m_subwin=MathMax(0,::ChartWindowFind());
               else
                  m_subwin=0;
            }               
         void        Detach(void)                           { m_subwin=-1; CChart::Detach(); }
         int         SubWindow(void)                        { return m_subwin; }
         int         Width(void)                            { return WidthInPixels(); }
         int         Height(void)                           { return HeightInPixels(m_subwin); }
         int         SubwindowY(int subwin=-1)              { return CChart::SubwindowY(subwin<0 ? m_subwin : subwin); }

      bool           ColorCandleBull(const color newcolor)  { return CChart::ColorCandleBull(newcolor); }
      bool           ColorBarUp(const color newcolor)       { return CChart::ColorBarUp(newcolor); }
   };

CChartExt __Chart;
   
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   int yoff=__Chart.SubwindowY();

   __Chart.ColorBarUp(__Chart.ColorCandleBull());        // <---- Warning message
   return INIT_SUCCEEDED;
  }
Doerk Hilger  

And another example. Imo it cannot be right that I have to overload ALL functions explicitly from the base class to avoid the warning message.
Text(void) is defined only once in CBase and should be accessible that way without any doubts. 


class CBase
   {
      public:
      bool Text(string text, int index=0) { return true; }
      string Text(int index=0) { return NULL; }
   };
   
class CDev : public CBase
   {
      public:
      void Text(string text1, string text2) {}
   };

  
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   CDev dev;
   string value=dev.Text();
   return INIT_SUCCEEDED;
  }
Alain Verleyen  
Doerk Hilger:

Hi,

I am not able to solve this. The basic idea is this code, but it produces the warning message for line 31. 


After changing line 31, which isn´t understandable why, to this

I still get the warning message at the second position. 

Is the compiler correct here or am I totally wrong?

Thanks in advance 

Are ever making a research on the forum before posting ? This has already been discussed.

Deal with it, it's done intentionally by Metaquotes.

Doerk Hilger  
Alain Verleyen:

Are ever making a research on the forum before posting ? This has already been discussed.

Deal with it, it's done intentionally by Metaquotes.

Yes, I use the search but I am not able to read russian language ;)

And, the other stuff I found, I checked upfront and it does not answer the question - does not help.

Please check the last example to understand, that we talk about different things.

Petr Nosek  
Doerk Hilger:

And another example. Imo it cannot be right that I have to overload ALL functions explicitly from the base class to avoid the warning message.
Text(void) is defined only once in CBase and should be accessible that way without any doubts. 


The new behaviour means that the called parent method is hidden by the descendant method. You have to explicitly specify the instance of the called method in order to avoid a warning.

class CBase
   {
      public:
      bool Text(string text, int index=0) { return true; }
      string Text(int index=0) { return NULL; }
   };
   
class CDev : public CBase
   {
      public:
      void Text(string text1, string text2) {}
   };

  
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   CDev dev;
   string value=dev.CBase::Text();
   return INIT_SUCCEEDED;
  }
Doerk Hilger  
Petr Nosek:

The new behaviour means that the called parent method is hidden by the descendant method. You have to explicitly specify the instance of the called method in order to avoid a warning.

And this is meant for real by MQ or is this a compiler bug? I don´t get the sense at all. 

Alain Verleyen  
Doerk Hilger :

Yes, I use the search but I am not able to read russian language ;)

And, the other stuff I found, I checked upfront and it does not answer the question - does not help.

Please check the last example to understand, that we talk about different things.

The automatic translation is working very well nowadays.I provided the link to the explanation here :

In summary, overloading like you are doing is bad design and also it doesn't compile in C++. I had also some situations like that in my code and after some thinking I do agree with Metaquotes, it's dirty work.

Forum on trading, automated trading systems and testing trading strategies

New version of MetaTrader 5 build 2085 platform: Python integration and massive improvements in the strategy tester

Renat Fatkhullin , 2019.09.09.07 11:08

Took your code from # 473 and redid it in MQL5:

 class A
  {
public :  
   int                Test( int a) { return 0 ; }
  };
class B : public A
  {
public :  
   int                Test( int a, int b) { return 0 ; }
  };

void OnStart ()
  {
   B b;
   b.Test( 1 );
  }

Conclusion: compiled with a good hint, which helps a lot in a complex class hierarchy, where they are easily confused with hidden methods

deprecated behavior, hidden method calling will be disabled in a future MQL compiler version
0 error(s), 1 warning(s), 114 msec elapsed

To understand the importance of such warnings, one has to deal with large complex projects for many years. In fact, such a [overlapping] of methods is obviously a design error and dirty work.

Moreover, we so far allow this overlap, only by warning. But MSVC 2017 generally prohibits such use:

 class A
  {
public :  
   int                Test( int a) { return 0 ; }
  };
class B : public A
  {
public :  
   int                Test( int a, int b) { return 0 ; }
  };

int main()
{
   B b;
   b.Test( 1 );
}


error C2660: 'B::Test' : function does not take 1 arguments
note: see declaration of 'B::Test' 

Clang / LLVM 8 also prohibits, suggesting an access option through A :: Test

error : too few arguments to function call, expected 2, have 1; did you mean 'A::Test'?
note: 'A::Test' declared here

So the claims against us are unfounded.

Alain Verleyen  
Petr Nosek:

The new behaviour means that the called parent method is hidden by the descendant method. You have to explicitly specify the instance of the called method in order to avoid a warning.

That's the fast fix, I am suggesting to think better about the design.
Petr Nosek  
Doerk Hilger:

And this is meant for real by MQ or is this a compiler bug? I don´t get the sense at all. 

I'm sure that it is not a bug. MQL is based on C ++ and this behaviour is standard for C++. See Alain's post.

Reason: