Deprecated behavior, hidden method calling will be disabled in a future MQL compiler version - page 5

 

Here is how to do it properly, btw:


interface iBase
{
    public:
    void f(string p_in);
    void f(void);
};

class Base : public iBase
{
    virtual void f(string p_in) = 0; //    { Print(__FUNCSIG__); }
};

class A : public Base
{
    public:
    virtual void f(string p_in)     { Print(__FUNCSIG__); }
    virtual void f(void)            { Print(__FUNCSIG__); }
};


class B : public A
{
    public:
    //virtual void f(string p_in)     { f(p_in); }
    virtual void f(void)            { Print(__FUNCSIG__); }
};




int Start()
{
   A a;
   a.f();
   a.f("1"); 

   B b;
   b.f();
   b.f("1"); // deprecated behavior, hidden method calling will be disabled in a future MQL compiler version
   
   iBase* i_face = GetPointer(b);
   
   i_face.f("A");

    return(NULL);
}
 
Thank you all for your contributions and for the clarification.
 
Dominik Egert #:

Here is how to do it properly, btw:


So my example could also work like this (the method doesn't even have to be virtual):


#include <Trade\SymbolInfo.mqh>

class CSymInfo : public CSymbolInfo
  {
public:
   bool              Name(const string name) { return(CSymbolInfo::Name(name));  }
  };

void OnStart()
  {
   CSymInfo symbolInfoDerived;
   CSymbolInfo *symbolInfo = GetPointer(symbolInfoDerived);
   symbolInfo.Name(_Symbol);
   string name = symbolInfo.Name();
  }
 
Petr Nosek #:

So my example could also work like this (the method doesn't even have to be virtual):


In this example because the Name is not virtual there is no override and so there is no dynamic runtime resolution, and you just bypass the Name method in the derived. It could as well be omitted at all, it is not called anyway.

 
Amir Yacoby #:

It could as well be omitted at all, it is not called anyway.

I'm sorry, but I don't understand what "IT" is.

What can be omitted? What is not called anyway?

 
Petr Nosek #:

I'm sorry, but I don't understand what "IT" is.

What can be omitted? What is not called anyway?

Run it in the debug mode and check if the Name of the base or the derived is called.

 
Amir Yacoby #:

Run it in the debug mode and check if the Name of the base or the derived is called.

Thanks, that surprised me.

In that case, of course, it's not a usable solution and it remains to either explicitly call a method from the parent class or to redeclare all overloaded methods in the derived class even though I only want to change the behavior of one of them.

 
Petr Nosek #:

Thanks, that surprised me.

In that case, of course, it's not a usable solution and it remains to either explicitly call a method from the parent class or to redeclare all overloaded methods in the derived class even though I only want to change the behavior of one of them.

As you understood already, the main issue you get here is due to the overloaded functions in the parent class. But even if there was no overload, so only one method you want to change the behaviour, it's still a bad idea to do it using inheritance, it leads to some surprises as you saw.

The best approach is to use composition instead. The annoying part is you will have to write wrapper functions for all the methods you want to access publicly, as MQL doesn't have the "using" keyword/concept, but it remains the best practice.

And I want to place emphasis on what someone else said, you should avoid using MQL "standard" library as much as possible, as it's terrible and very poorly designed.

 
Alain Verleyen #:

As you understood already, the main issue you get here is due to the overloaded functions in the parent class. But even if there was no overload, so only one method you want to change the behaviour, it's still a bad idea to do it using inheritance, it leads to some surprises as you saw.

The best approach is to use composition instead. The annoying part is you will have to write wrapper functions for all the methods you want to access publicly, as MQL doesn't have the "using" keyword/concept, but it remains the best practice.

And I want to place emphasis on what someone else said, you should avoid using MQL "standard" library as much as possible, as it's terrible and very poorly designed.

In MQL4, I almost never used the "standard" libraries and I had good reason to do so. Now that I'm switching to MQL5, I'm familiarizing myself with the "standard" libraries for now so I don't reinvent the wheel. But it looks like it will be less time consuming to write all the necessary libraries by myself.  I can easily use (copy-paste) some "ideas" from the "standard" ones.

You're right that using composition is more appropriate than using inheritance in most cases. Especially if the parent class is made up of someone else. 

 
Alain Verleyen #:
The best approach is to use composition instead.

What exactly do you mean by composition? Could you give an example or link to an example, please?