OLP. Problemas de aplicación - página 4

 
Yedelkin:

Pregunta. Después de declarar una función virtual con un determinado conjunto de parámetros y tipos en una clase padre, ¿es posible cambiar el número y los tipos de parámetros de las funciones virtuales correspondientes en las clases descendientes?

Por un lado, el Manual de Referencia afirma que "una función virtual puede ser sustituida en una clase derivada . Laelección de ladefinición de la función a la que se llama para la función virtual se hace de forma dinámica (en tiempo de ejecución). Un caso típico es cuando una clase base contiene y las clases derivadas tienen sus propias versiones de esa función". Por otra parte, los ejemplos que se dan en el Manual de referencia se refieren a casos en los que las funciones virtuales tienen cuerpos de definición de funciones diferentes y no cabeceras de definición de funciones.

Que yo recuerde es posible. Pero hay que tener mucho cuidado con los tipos y el número de parámetros.

También hay que tener cuidado con los tipos de valores pasados y los valores por defecto.

He aquí algunos ejemplos para simplificar.

Esta variante servirá para ello.

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

Este no lo hace (o mejor dicho, quizá funcione pero con algunos fallos y ciertas reservas).

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

Lo mismo ocurre cuando se recargan los métodos dentro de una clase.

 
mql5:
Sólo una copia exacta de la definición, a excepción de la configuración por defecto (los valores predeterminados pueden variar, pero es mejor no usar esto)
¿Quiere decir "sólo una copia exacta de la cabecera de la definición"? Al fin y al cabo, la definición de la función incluye la cabecera más el cuerpo. Los cuerpos de los ejemplos son definitivamente diferentes.
 

Interesante, según tengo entendido, la virtualización de funciones y la sobrecarga de funciones son cosas ligeramente diferentes. Ymql5 dice que en la virtualización de funciones debe haber una copia dura de la cabecera de la función (no tengo en cuenta los parámetros por defecto).

 
Yedelkin:

Interesante, según tengo entendido, la virtualización de funciones y la sobrecarga de funciones son cosas un poco diferentes. Ymql5 dice que en la virtualización de funciones debe haber una copia dura de la cabecera de la función (no estoy teniendo en cuenta los parámetros por defecto).

> Pregunta. Tras la declaración de una función virtual con un determinado conjunto de parámetros y sus tipos en una clase padre, ¿es posible cambiar el número y los tipos de parámetros de las funciones virtuales correspondientes en las clases descendientes?

Si he entendido bien, el hijo debe sobrecargar la funcionalidad del ancestro.

Francamente, no recuerdo haber hecho esas cosas con virtual (creo que sí), pero la afirmación sobre la sobrecarga es cierta: yo mismo cometí ese error una vez.

PS

Si todo se hace correctamente, según tengo entendido, el número de parámetros puede aumentar y disminuir. Las dificultades serán si el número de parámetros sigue siendo el mismo, pero sus tipos cambian...

 

De todos modos, he esbozado este ejemplo:

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);
     }

Resulta que, independientemente de si un método de función está sobrecargado o no en la clase C_C, se puede llamar a una función virtual con sólo tres parámetros - pointer.function(a1,a2,a3). En consecuencia, el programa nunca llegará al método de dos parámetros de la clase C_C cuando llame a las funciones virtuales. ¿Verdad?

 
Yedelkin:

De todos modos, he esbozado este ejemplo:

Resulta que, independientemente de si un método de función está sobrecargado o no en la clase C_C, se puede llamar a una función virtual con sólo tres parámetros - pointer.function(a1,a2,a3). En consecuencia, el programa nunca llegará al método de dos parámetros de la clase C_C cuando llame a las funciones virtuales. ¿Verdad?

Analizar lo que hace el programa insertando en constructores y destructores impresiones con la macro __FUNCTION__, será muy útil.

También añadiría que al declarar un puntero a una clase base, se construye un "túnel" hacia los descendientes a través de la clase base. Así, el compilador, al llamar a los descendientes de esta manera, sólo verá las funciones declaradas en la clase base. Si usted (incluso dentro del mismo programa) declara un objeto descendiente directamente, todas las funciones estarán disponibles en él.

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:

De todos modos, he esbozado este ejemplo:

Resulta que, independientemente de si un método de función está sobrecargado o no en la clase C_C, se puede llamar a una función virtual con sólo tres parámetros - pointer.function(a1,a2,a3). En consecuencia, el programa nunca llegará al método de dos parámetros de la clase C_C cuando llame a las funciones virtuales. ¿Verdad?

Por mi propia experiencia puedo recomendarte que empaques el código de la siguiente manera

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

Y puedes ver el archivo adjunto como ejemplo y entretenimiento.

No quería molestarme con punteros y new, así que simplemente declaré la clase de trabajo como una variable.

El Asesor Experto genera un número aleatorio 0/1 en intervalos de tiempo iguales y dependiendo del resultado realiza una de las dos funciones: MarketBuy / MarketSell.


Puedes hacerlo así si quieres

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);

Pero en este caso puede producirse un error debido al conflicto con

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


PS

Lo hice a mano, por eso puede haber algunas inexactitudes.

Pero, en principio, la idea básica puede entenderse.

Archivos adjuntos:
Forum.mq5  18 kb
 

Muchas gracias por los valiosos consejos y orientaciones. Definitivamente los utilizaré, pero me gustaría tener suficiente tiempo para la teoría y la práctica.

Interesting:

Por mi propia experiencia, puedo recomendar que se complete el código

double function(double a1, double a2)            {return(a1+a2);}
double function(double a1, double a2, double a3) {return(a2);}
¿Por qué hacerlo así? ¿Cuál es el escollo?
 
Yedelkin:

¿Por qué es así? ¿Cuál es el escollo?

Antes había un problema con eso, creo. Pero ahora no recuerdo cuáles.

De todos modos, me acostumbré a ello.

Normalmente no hay diferencia, por supuesto, al menos en mi ejemplo probé a intercambiar lugares y todo funcionó...

 
Interesting:

Creo que antes había un problema con eso. Pero ahora no recuerdo cuáles.

En cualquier caso, lo tendré en cuenta.
Razón de la queja: