Errores, fallos, preguntas - página 1678

 
Комбинатор:
Se puede utilizar para hacer un análogo de la palabra clave final, prohibiendo explícitamente la herencia posterior.
Pero como muestra el ejemplo anterior, no se puede hacer un análogo. Debe especificar final incluso para los métodos privados.
 
fxsaber:
Pero como muestra el ejemplo anterior, no se puede hacer un análogo. Debe especificar final incluso para los métodos privados.

Extraño. Para la herencia pública, el acceso máximo debe ser protegido, no privado.

¿Y la función del ejemplo se sobrecarga exactamente?

 
Комбинатор:

Extraño. Para la herencia pública, el acceso máximo debe ser protegido, no privado.

Y en el ejemplo, ¿la función está exactamente sobrecargada?

Sí. Acabo de descubrirlo yo mismo.

Si lo hace

BASE() {Func();} // вместо void Init() {Func();} Вызов  Base.Init() - убрать конечно.

puedes comprobarlo tú mismo después de ejecutarlo y ver si sabes lo que debe pasar.

 

En el registro de la terminal obtengo

2016.09.12 15:49:14.209 Simple_Test (RTS-9.16,M1)       array out of range in 'Simple_Test.mqh' (85,33)

ir torpemente a la ubicación especificada en el código fuente. Sería conveniente poder hacer doble clic en un mensaje de este tipo en el registro del terminal y llegar directamente a la línea especificada.

Si alguien lo apoya, que hable.

 
Sergei Vladimirov:

Lo clásico es una interfaz en una clase base con redefinición en las descendientes:

Lo clásico es cuando se anulan métodos protegidos/públicos-virtuales. Pero para los privados, no es tan obvio (en términos de aplicación). Gracias por la respuesta.
 
fxsaber:
Lo clásico es cuando se anulan los métodos virtuales protegidos/públicos. Pero para los privados, no es tan obvio (en términos de aplicación). Gracias por responder.

Sí, ya borré mi ejemplo sin ver tu respuesta, fue realmente desafortunado.

Actualización. Yo mismo me confundí en lo básico mientras te contestaba. Todo era correcto en ese ejemplo, no debería haberlo borrado. El mismo ejemplo de nuevo con un ejemplo de uso:

class CAnimal
{
private:
   void virtual Speak(){}
};

class CDog : public CAnimal
{
public:
   void Speak(){Print("Гав!");}
};

class CBigDog : public CDog
{
public:
   void Speak(){Print("Громкий гав!");}
};

void OnStart()
{
   CDog oDog;
   oDog.Speak();
   
   CBigDog oBigDog;
   oBigDog.Speak();
   
   CDog* pDog = &oBigDog; 
   pDog.Speak();       // "Громкий гав!", а не "Гав!", как было бы без виртуального метода
}
 
Sergei Vladimirov:

Actualización. Yo mismo me confundí en lo básico mientras te contestaba. Todo era correcto en ese ejemplo, no debería haberlo borrado. De nuevo con un ejemplo de cómo utilizarlo:

No es un buen ejemplo, ya que no vemos que se utilice la interfaz CAnimal en ninguna parte. Sí, también han hecho públicas dos descendencias. Entiendo el tema, así que está bien.
 
#property indicator_buffers 1 + 1

El compilador no hace un dos.

 
fxsaber:
Este no es un buen ejemplo, ya que no vemos que se utilice la interfaz CAnimal en ninguna parte. También se han hecho públicos dos descendientes. Entiendo el tema, así que está bien.

Un ejemplo normal. Un animal abstracto básicamente hace algún sonido, pero indefinido, por lo que no podemos llamar al método Speak() sobre él; sólo puede ser llamado sobre un animal de una especie específica. Por lo tanto, declaramos un método virtual cerrado en una clase base, y lo anulamos en las descendientes y lo abrimos.

 
Sergei Vladimirov:

Un ejemplo normal. Un animal abstracto básicamente hace algún sonido, pero indefinido, por lo que no podemos llamar al método Speak() sobre él; sólo puede ser llamado sobre un animal de una especie específica. Por lo tanto, declaramos un método virtual cerrado en una clase base, y lo anulamos en las descendientes y lo abrimos.

Sería útil hacerla privada también en las clases descendientes. Para una mejor comprensión. No es el punto, en resumen.