PLO. Application issues - page 4

 
Yedelkin:

Question. After declaring a virtual function with a certain set of parameters and types in a parent class, is it possible to change the number and types of parameters of corresponding virtual functions in descendant classes?

On the one hand, the Reference Manual states that "a virtual function may be substituted in a derived class. The choice of which function definition to call for the virtual function is made dynamically (at runtime). A typical case is when a base class contains and derived classes have their own versions of that function". On the other hand, the examples given in the Reference Manual refer to cases where virtual functions have different function definition bodies rather than function definition headers .

As far as I remember it is possible. But you have to be absolutely careful about the types and number of parameters.

You also have to be careful with the types of values passed and default values.

Here are some examples for simplicity.

This variant will do the trick.

boll MyFunction(int Param);
boll MyFunction(int Param1,int Param2);

This one does not (or rather, maybe it will work but with some bugs and certain reservations).

//Ели второй параметр будет упущен, то компилятор может и не "понять" смысла всего задуманного
boll MyFunction(int Param);
boll MyFunction(int Param1,int Param2 = 0);
//Так тоже может не прокатить по причине совпадения типов у второго параметра
boll MyFunction(int Param1,color Param2);
boll MyFunction(int Param1,int Param2);

Exactly the same thing happens when you reload methods inside a class.

 
mql5:
Only an exact copy of the definition, except for the default settings (defaults may vary, but it's best not to use this)
Do you mean "only an exact copy of the definition header "? After all, the function definition includes the header plus the body. The bodies in the examples are definitely different.
 

Interesting, as I understand it, function virtualization and function overloading are slightly different things. Andmql5 says that in function virtualisation there should be a hard copy of function header (I don't take default parameters into account).

 
Yedelkin:

Interesting, as I understand it, function virtualization and function overloading are a bit different things. Andmql5 says that in functions virtualization there should be a hard copy of function header (I'm not taking into account default parameters).

> Question. After declaration of a virtual function with a certain set of parameters and their types in a parent class, is it possible to change number and types of parameters of corresponding virtual functions in descendant classes?

If I understand correctly, the child must overload the ancestor's functionality.

Frankly speaking, I don't remember doing such things with virtual (I think I did), but the statement about overloading is true - I made that mistake once myself.

PS

If everything is done correctly, as I understand it, the number of parameters can be both increased and decreased. Difficulties will be if the number of parameters remains the same, but their types are changed...

 

Anyway, I've sketched this example:

class C_A             //родительский класс
{
 public:
 virtual double function(double a1, double a2, double a3) { return; }
}
class C_B : public C_A
{
 public:
 virtual double function(double a1, double a2, double a3) { return(a1);   }
}
class C_C : public C_A
{
 public:      
 virtual double function(double a1, double a2, double a3) { return(a2);   }
        double function(double a1, double a2)           { return(a1+a2); }
}
//где-то в программе объявляем указатель
C_A  *pointer;
int random=rand()%2;
   switch(random)
     {
      case 0: pointer=new C_B; break;
      case 1: pointer=new C_C; break;
     }

//вызываем виртуальный метод
   if(pointer!=NULL)
     {
      pointer.function(a1,a2,a3);
     }

It turns out that regardless of whether or not a function method is overloaded in class C_C, a virtual function can be called with only three parameters - pointer.function(a1,a2,a3). Correspondingly, the program will never get to the two-parameter method from the C_C class when calling the virtual functions. Right?

 
Yedelkin:

Anyway, I've sketched this example:

It turns out that regardless of whether or not a function method is overloaded in class C_C, a virtual function can be called with only three parameters - pointer.function(a1,a2,a3). Correspondingly, the program will never get to the two-parameter method from the C_C class when calling the virtual functions. Right?

Analyze what the program does by inserting into constructors and destructors prints with __FUNCTION__ macro, it will be very useful.

I would also add that declaring a pointer to a base class, you thus construct a "tunnel" to the descendants through the base class. Thus the compiler, when calling descendants in this way, will see only functions declared in the base class. If you (even within the same program) declare a descendant object directly, all functions will be available in it.

class C_A             //родительский класс
{
 public:
 virtual double function(double a1, double a2, double a3) { return; }
}
class C_B : public C_A
{
 public:
 virtual double function(double a1, double a2, double a3) { return(a1);   }
}
class C_C : public C_A
{
 public:      
 virtual double function(double a1, double a2, double a3) { return(a2);   }
        double function(double a1, double a2)           { return(a1+a2); }
}
//где-то в программе объявляем указатель
C_A  *pointer;
int random=rand()%2;
   switch(random)
     {
      case 0: pointer=new C_B; break;
      case 1: pointer=new C_C; break;
//вызываем виртуальный метод
   if(pointer!=NULL)
     {
      pointer.function(a1,a2,a3);
     }
C_С  *new_pointer=new C_C;
      new_pointer.function(a1,a2);
 
Yedelkin:

Anyway, I've sketched this example:

It turns out that regardless of whether or not a function method is overloaded in class C_C, a virtual function can be called with only three parameters - pointer.function(a1,a2,a3). Correspondingly, the program will never get to the two-parameter method from the C_C class when calling the virtual functions. Right?

From my own experience I can recommend you to pack the code in the following way

double function(double a1, double a2)            {return(a1+a2);}
double function(double a1, double a2, double a3) {return(a2);}

And you can see the attached file as an example and entertainment.

I didn't want to bother with pointers and new, so I simply declared the working class as a variable.

The Expert Advisor generates a random number 0/1 at equal intervals and depending on the result performs one of two functions: MarketBuy / MarketSell.


You can do it this way if you want

bool MarketBuy(string SymbolTitle,double LotSize,double TP = 0.0,double SL = 0.0);
bool MarketSell(string SymbolTitle,double LotSize,double TP = 0.0,double SL = 0.0);

But in this case a bug may occur because of the conflict with

bool MarketBuy(string SymbolTitle,double LotSize);
bool MarketSell(string SymbolTitle,double LotSize);


PS

I made it by hand, that's why there may be some inaccuracies.

But in principle the basic idea can be understood.

Files:
Forum.mq5  18 kb
 

Thank you very much for the valuable advice and guidance! I will definitely use them, but I wish I had enough time for both theory and practice.

Interesting:

From my own experience, I can recommend so complete the code

double function(double a1, double a2)            {return(a1+a2);}
double function(double a1, double a2, double a3) {return(a2);}
Why do it this way? What is the pitfall?
 
Yedelkin:

Why is it like that? What is the pitfall?

There used to be a problem with that, I think. But I can't remember which ones now.

Anyway, I got used to it.

Usually there is no difference of course, at least in my example I tried swapping places and it all worked...

 
Interesting:

There used to be a problem with that, I think. But I can't remember which ones now.

OK, in any case - I'll keep that in mind.
Reason: