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

 
Amir Yacoby #:
The problem is that CSymbolInfo has 2 Name() methods, one with parameters and one parameterless.

By redefining Name() in your derived class CSymInfo with a specific parameter ( const string name ), you've hidden the parameterless version of Name() from the base class. This is what triggers the compiler warning.

OK, I understand why the compiler writes me a warning. Still, it seems like strange behavior to me.

Just to be sure, I'll repeat my conclusion and I'll be glad for confirmation, or for a demonstration of how this problem can be bypassed.

If there are 10 overloaded methods in the parent class and I want to override the behavior of only one of them in the derived class, I still have to declare all 10 in the derived class.

 
Petr Nosek #:

Thanks for the link. So far I haven't really understood how it relates to my question, but I'll keep trying :-)

Just to be sure, I'll repeat my conclusion and I'll be glad for confirmation, or for a demonstration of how this problem can be bypassed.

If there are 10 overloaded methods in the parent class and I want to override the behavior of only one of them in the derived class, I still have to declare all 10 in the derived class.

Yes. - Thats how it is intended to be.

Overloading has to be done in the same scope. - If you declare the one function, you intend to override as virtual, it will (actually I am not sure) be fine. But it requires you to make changes to the base-class. - This is called overriding.

But generally, you need to have the same functions signatures in the same scope, if you want to overload.

 
Petr Nosek #:

OK, I understand why the compiler writes me a warning. Still, it seems like strange behavior to me.

Just to be sure, I'll repeat my conclusion and I'll be glad for confirmation, or for a demonstration of how this problem can be bypassed.

If there are 10 overloaded methods in the parent class and I want to override the behavior of only one of them in the derived class, I still have to declare all 10 in the derived class.

Again, as long as there is no virtual base method - you did not override any method.

First thing to understand, because you wrote that you override but you didn't.


 

What is causing the warning in the code below? I simply overridden one of the methods overloaded in the base class.

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

class A : public Base
  {
public:
   void f(void) override { Print(__FUNCSIG__); }
  };

void OnStart()
  {
   A a;
   a.f();
   a.f("1"); // deprecated behavior, hidden method calling will be disabled in a future MQL compiler version
  }
 
Vladislav Boyko #:

What is causing the warning in the code below? I simply overridden one of the methods overloaded in the base class.

because in your class A , the method f(string) from the base class Base is hidden, not overridden.

It happens because in the base class, there are two overloaded versions of f.

And in the derived class you overrode only void f(void) but not void f(string).

By declaring f(void) in the derived class, the compiler hides all other overloads of f from the base class in the derived class scope.

As a result: a.f() calls the overriden A::f(void) correctly. 
And a.f("1") tries to resolve to A::f(string), but no such method exists in A. The base class version is hidden, which triggers the warning.

 
Amir Yacoby #:

Again, as long as there is no virtual base method - you did not override any method.

First thing to understand, because you wrote that you override but you didn't.


I apologize for using the wrong term, but I will still ask you to confirm my conclusion (with the already correct term).

If there are 10 overloaded methods in the parent class and I want to hide the behavior of only one of them in the derived class, I still have to declare all 10 in the derived class.

 
Petr Nosek #:

I apologize for using the wrong term, but I will still ask you to confirm my conclusion (with the already correct term).

If there are 10 overloaded methods in the parent class and I want to hide the behavior of only one of them in the derived class, I still have to declare all 10 in the derived class.

Here is how you would be required to do it, since MQL5 does not support "using" keyword:


class Base
{
    public:
    virtual void f(string p_in) = 0;
    virtual void f(void)        { 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) { A::f(p_in); }
    virtual void f(void)        { Print(__FUNCSIG__); }
};


EDIT: So my previous post was actually not quite correct.

 
Petr Nosek #:

I apologize for using the wrong term, but I will still ask you to confirm my conclusion (with the already correct term).

If there are 10 overloaded methods in the parent class and I want to hide the behavior of only one of them in the derived class, I still have to declare all 10 in the derived class.

Yes because the ones that are not declared become hidden.

One way is to use this (if you don't need custom behaviour for every overload)

a.Base::f("1");
Or explicitly override all methods.
 
Amir Yacoby #:

because in your class A , the method f(string) from the base class Base is hidden, not overridden.

It happens because in the base class, there are two overloaded versions of f.

And in the derived class you overrode only void f(void) but not void f(string).

By declaring f(void) in the derived class, the compiler hides all other overloads of f from the base class in the derived class scope.

As a result: a.f() calls the overriden A::f(void) correctly. 
And a.f("1") tries to resolve to A::f(string), but no such method exists in A. The base class version is hidden, which triggers the warning.

Yes, thats the problem with the scope. - But I fell for it as well, just a post ago... - OMG

 
Amir Yacoby #:

because in your class A , the method f(string) from the base class Base is hidden, not overridden.

It happens because in the base class, there are two overloaded versions of f.

And in the derived class you overrode only void f(void) but not void f(string).

By declaring f(void) in the derived class, the compiler hides all other overloads of f from the base class in the derived class scope.

As a result: a.f() calls the overriden A::f(void) correctly. 
And a.f("1") tries to resolve to A::f(string), but no such method exists in A. The base class version is hidden, which triggers the warning.

Amir Yacoby #:

Yes because the ones that are not declared become hidden.

One way is to use this (if you don't need custom behaviour for every overload)

Or explicitly override all methods.

I understand, thank you!

Amir Yacoby #:
Or explicitly override all methods.

Perhaps an illustrative example will be useful to someone:

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

class A : public Base
  {
public:
   void f(void) override     { Print(__FUNCSIG__); }
   void f(string x) override { Base::f(x);         }
  };

void OnStart()
  {
   A a;
   a.f();    // void A::f()
   a.f("1"); // void Base::f(string)
  }