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

 
Petr Nosek #:

I understand that by declaring the Name(const string name) method in the derived class I hide (override) the same method in the parent class. But I thought that the Name(void) and Name(const string name) methods are overloaded methods and each has a different signature. If I don't declare Name(void) in the derived class, but only Name(const string name), then when calling Name(void) there is no other Name(void) than the one defined in the base class. So the code should not be ambiguous due to the same signatures. I understand from the documentation https://www.mql5.com/en/docs/basis/oop/overload that the compiler should first look for the Name(void) method in the derived class (it won't find it there), then in the parent class and find it there and use it.

I didn't know that declaring an overloaded Name(const string name) method in a derived class hides not only Name(const string name) in the parent class, but also Name(void) in the parent class. One has to keep learning, but I'm not sure if this is a violation of the polymorphism principle. If anyone has a link (maybe to another programming language, since I couldn't find anything like that with the MQL documentation) where this is explained, I'd be very happy.


If I understood you correct, its the other way around. Thus that's why you are getting the warning.

Edit:
So, basically, if you over load in a derived class a base class function, you get that warning.

If you also declare that overloaded function in your derived class, the warning will disappear.
 
Dominik Egert #:

If I understood you correct, its the other way around. Thus that's why you are getting the warning.

Edit:
So, basically, if you over load in a derived class a base class function, you get that warning.

If you also declare that overloaded function in your derived class, the warning will disappear.

There are two (overloaded) methods named Name (Name(const string name) and Name(void)) declared in the base class. If I declare only one method named Name (in my case Name(const string name)) in the derived class, I get a warning from the compiler. If I also declare a second overloaded function (Name(void)) in the derived class, the warning disappears.

 
Petr Nosek #:

There are two (overloaded) methods named Name (Name(const string name) and Name(void)) declared in the base class. If I declare only one method named Name (in my case Name(const string name)) in the derived class, I get a warning from the compiler. If I also declare a second overloaded function (Name(void)) in the derived class, the warning disappears.

Yes.

This is because in first scenario you are implicit merging the vTables of the classes, which is deprecated behavior.

Edit: its actually an overwrite and after that an overload. First comes the overwrite, then the overload.

Overloads must be on same scope, overwrite is across scope boundaries. Base class to derived class is a scope crossing, and needs to be complete by declaration.
 
Petr Nosek #:
But I thought that the Name(void) and Name(const string name) methods are overloaded methods and each has a different signature.

https://www.mql5.com/en/docs/basis/function/functionoverload

Function overloading is a process of creating several functions with the same name, but different parameters. This means that in overloaded variants of a function, the number of arguments and/or their type must be different. A specific function variant is selected based on the correspondence of the list of arguments when calling the function, to the list of parameters in the function declaration.

Overloading implies different signatures (different number and/or different types of arguments).

The signatures of your new methods in the derived class exactly match the signatures of the methods from CSymbolInfo:

class CSymbolInfo : public CObject
  {
protected:
   string            m_name;                       // symbol name
public:
   string            Name(void) const { return(m_name); }
   bool              Name(const string name);
  };

So you're making ambiguous code, not overloading.

[edit]

Dominik Egert #:
Yes.

This is because in first scenario you are implicit merging the vTables of the classes, which is deprecated behavior.

Edit: its actually an overwrite and after that an overload. First comes the overwrite, then the overload.

Overloads must be on same scope, overwrite is across scope boundaries. Base class to derived class is a scope crossing, and needs to be complete by declaration.
In that case there can be no vTables and overrides because CSymbolInfo has no virtual methods.
 
Vladislav Boyko #:

Overloading implies different signatures (different number and/or different types of arguments).

The signatures of your new methods in the derived class exactly match the signatures of the methods from CSymbolInfo:

So you're making ambiguous code, not overloading.

See my previous post.

Edit: its not ambiguous, its deprecated.
 
Dominik Egert #:
Yes.

This is because in first scenario you are implicit merging the vTables of the classes, which is deprecated behavior.

Edit: its actually an overwrite and after that an overload. First comes the overwrite, then the overload.

Overloads must be on same scope, overwrite is across scope boundaries. Base class to derived class is a scope crossing, and needs to be complete by declaration.

Do you please have a reference from which I can study how the implicit merging inTables works (even though the methods are not virtual)?

In other words, if there are 10 overloaded methods in the base 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. That seems pretty impractical to me.

 
Petr Nosek #:

Do you please have a reference from which I can study how the implicit merging inTables works (even though the methods are not virtual)?

In other words, if there are 10 overloaded methods in the base 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. That seems pretty impractical to me.


This should give clarity in some sense:

 
Dominik Egert #:

A global function does not hide a class method.

How did you come up with that conclusion?

It's not my conclusion, a function with same name in inner scope as the one in outer scope - the inner one hides the outer one.

This is c++ and also MQL5.

The reason of the warning:



is that there is an ambigiuity in hiding (not overriding) which is implicitly allowed in current MQL5 version which will not be allowed in future versions.

 

Vladislav Boyko #:

So you're making ambiguous code, not overloading.

I'm sorry, but I don't think we understand each other. There is no problem with ambiguous code in the sample code. The problem is not with the Name(const string name) method that I declared in the derived class, but the problem is with the Name(void) method of the parent class, which is not declared in the derived class at all.

 
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.