#property copyright"Copyright 2011, MetaQuotes Software Corp."#property link"https://www.mql5.com"#property version"1.00"//+------------------------------------------------------------------+//| Класс-пример с несколькими типами доступа |//+------------------------------------------------------------------+class CBaseClass
{
private: //--- закрытый член недоступен из потомковint m_member;
protected: //--- защищенный метод доступен из базового класса и его потомковint Member(){return(m_member);}
public: //--- конструктор класса доступен всем
CBaseClass(){m_member=5;return;};
private: //--- закрытый метод для присвоения значения члену m_membervoid Member(int value) { m_member=value;};
};
//+------------------------------------------------------------------+//| Производный класс с ошибками |//+------------------------------------------------------------------+class CDerived: public CBaseClass // public наследование можно не указывать, оно по умолчанию
{
public:
void Func() // определим в потомке функцию с обращениями к членам базового класса
{
//--- попытка модификации закрытого члена базового класса
m_member=0; // ошибка, закрытый член базового класса никому не доступен
Member(0); // ошибка, закрытый метод базового класса не доступен в потомках
Es extraño lo del constructor:
public: //--- конструктор класса доступен всем
CBaseClass(){m_member=5;return;};
¿Por qué hay un operador de retorno aquí?
Es la primera vez que veo que se utiliza este operador en el constructor. De hecho, el constructor se llama automáticamente. Y habrá una salida de todos modos. ¿Tiene sentido este operador en el constructor?
Es la primera vez que veo que se utiliza este operador en el constructor. De hecho, el constructor se llama automáticamente. Y habrá una salida de todos modos. ¿Tiene sentido este operador en el constructor?
No es necesario en este ejemplo, pero puede haber una inicialización compleja cuando se necesita una salida temprana.
El constructor y el destructor son funciones normales. Sólo el constructor y el destructor por defecto son llamados automáticamente. Los demás son llamados por el usuario.
El libro de texto da este ejemplo en relación con el polimorfismo:
//--- Базовый классclass CShape
{
protected:
int m_type; // тип фигурыint m_xpos; // X - координата точки привязкиint m_ypos; // Y - координата точки привязкиpublic:
void CShape(){m_type=0;}; // конструктор, тип равен нулюint GetType(){return(m_type);};// возвращает тип фигурыvirtualdouble GetArea(){return (0); }// возвращает площадь фигуры
};
//--- производный класс Кругclass CCircle : public CShape // после двоеточия указывается базовый класс,
{ // от которого производится наследование private:
double m_radius; // радиус кругаpublic:
void CCircle(){m_type=1;}; // конструктор, тип равен 1 void SetRadius(double r){m_radius=r;};
virtualdouble GetArea(){return (3.14*m_radius*m_radius);}// площадь круга
};
class CSquare : public CShape // после двоеточия указывается базовый класс,
{ // от которого производится наследование private:
double m_square_side; // сторона квадратаpublic:
void CSquare(){m_type=2;}; // конструктор, тип равен 2 void SetSide(double s){m_square_side=s;};
virtualdouble GetArea(){return (m_square_side*m_square_side);}//площадь квадрата
};
Hay una cosa que no entiendo. Si utilizamos objetos de función hijos para las llamadas, es decir, los métodos derivados CCircle y CSquare, entonces el área de GetArea() puede ser calculada saltándose las declaraciones en la clase base. Es decir, no crear funciones virtuales en la clase base en absoluto, y en los métodos derivados crear un método simple y ya está. Entonces, ¿por qué necesitamos una función virtual?
Es interesante ver un ejemplo adecuado y lógico, en el que se puede ver que las funciones virtuales aportan algún beneficio. Porque lo que vi no era lógico, al menos para mí. Me gustaría entenderlo igualmente.
El libro de texto da este ejemplo en relación con el polimorfismo:
Hay una cosa que no entiendo. Si utilizamos objetos de función hijos para las llamadas, es decir, los métodos derivados CCircle y CSquare, entonces el área de GetArea() puede ser calculada saltándose las declaraciones en la clase base. Es decir, no crear funciones virtuales en una clase base en absoluto, y en los métodos derivados crear un método simple y ya está. Entonces, ¿por qué necesitamos una función virtual?
Es interesante ver un ejemplo adecuado y lógico, en el que se ve que las funciones virtuales aportan algún beneficio. Porque lo que vi no era lógico, al menos para mí. Me gustaría entenderlo igualmente.
Esta es la muestra más sencilla para entender el polimorfismo. Para conseguirlo rápidamente.
Hay casos complicados. Lo aplicará cuando lo necesite. No tiene sentido molestarse ahora. Cuando la tarea esté hecha, tendrás que pensar en ella.
Por ejemplo, tengo una clase base con todas las interfaces de lectura/escritura posibles. También tiene métodos virtuales privados (2 en total - lectura/escritura), que vinculan esta interfaz en la clase base con las clases derivadas. En realidad las clases derivadas pueden ser cualquiera donde haya trabajo con archivos (archivos, mapeo, canales, internet). Cada una de las clases derivadas define estos métodos virtuales de forma diferente, pero todas las clases tienen la misma interfaz de la clase base.
El libro de texto da este ejemplo en relación con el polimorfismo:
Hay una cosa que no entiendo. Si utilizamos los objetos de la función hija para las llamadas, es decir, los métodos derivados CCircle y CSquare, entonces el área de GetArea() se puede calcular omitiendo las declaraciones en la clase base. Es decir, no crear funciones virtuales en la clase base en absoluto, y en los métodos derivados crear un método simple y ya está. Entonces, ¿por qué necesitamos una función virtual?
Es interesante ver un ejemplo adecuado y lógico, en el que se ve que las funciones virtuales aportan algún beneficio. Porque lo que vi no era lógico, al menos para mí. Quiero entenderlo igualmente.
Intentaré esbozar una pequeña muestra:
#property strict#property show_inputsenum Mes_type {
m1,
m2
};
input Mes_type mes_t; // Выберите тип сообщенияclass Message {
public:
virtualvoid action() {};
};
class Mes1 : public Message {
public:
virtualvoid action() {Alert("Типичные ошибки в программах");}
};
class Mes2 : public Message {
public:
virtualvoid action() {Alert("Оффлайновые графики");}
};
voidOnStart() {
// Формируем входные данные для какого-то алгоритма//////////////////////////////////////////
Message *mes; //switch(mes_t) //
{ //case m1: //
mes = new Mes1; //break; //case m2: //
mes = new Mes2; //
} ///////////////////////////////////////////// Рабочий алгоритм//////////////////////////////////////////
mes.action(); ////////////////////////////////////////////delete mes;
}
Gracias a esta estructura, no necesitaremos entrar en el algoritmo de trabajo, que puede ser muy grande y complejo (todo está simplificado aquí), sólo tendremos que añadir un descendiente más, m3 en la enumeración y un caso más en el interruptor. Es decir, hemos unificado los datos de entrada, lo que evitará la edición en la parte principal del programa.
Por supuesto, esto sólo será apropiado si el algoritmo de trabajo acepta una variedad de tipos como entrada. Si sólo hay un tipo, todo esto es inútil.
El libro de texto da este ejemplo en relación con el polimorfismo:
Hay una cosa que no entiendo. Si utilizamos objetos de función hijos para las llamadas, es decir, los métodos derivados CCircle y CSquare, entonces el área de GetArea() puede ser calculada saltándose las declaraciones en la clase base. Es decir, no crear funciones virtuales en una clase base en absoluto, y en los métodos derivados crear un método simple y ya está. Entonces, ¿por qué necesitamos una función virtual?
Es interesante ver un ejemplo adecuado y lógico, en el que se puede ver que las funciones virtuales aportan algún beneficio. Porque lo que vi no era lógico, al menos para mí. Me gustaría entenderlo igualmente.
He aquí un ejemplo sencillo:
CShape* GetNewShape()
{
if( ... ) // Здесь какое-то условие.
returnnew CCircle();
elsereturnnew CSquare();
}
CShape* M[10];
for( int i = 0; i < 10; i++ )
{
M[i] = GetNewShape();
}
double WholeArea = 0.0;
for( int i = 0; i < 10; i++ )
{
WholeArea += M[i].GetArea();
}
Utilizamos la función GetArea() sin saber a qué forma se llama.
//---- SetColorBySend
TradingFunc::SetColorBySend (constcolor fc_ColorSendBuy, // Цвет открытия ордера на покупкуconstcolor fc_ColorSendSell) // Цвет открытия ордера на продажу
{
ColorBySend [2] = {fc_ColorSendBuy, fc_ColorSendSell};
}
El compilador generalmente está luchando contra esta asignación de elementos a la matrizColorBySend así:
¿Qué tiene esto que ver? ¿Es realmente necesario asignar valores elemento por elemento? ¿No es posible hacerlo como una lista? ¿Con qué está relacionado? Después de todo, así es como funciona la tarea incluso en el libro de texto...
El compilador jura esta asignación de elementos al array ColorBySend en general así:
¿Qué tiene esto que ver? ¿Es realmente necesario asignar valores elemento por elemento? ¿No es posible hacerlo como una lista? ¿Qué tiene que ver? Después de todo, así es como se hace la asignación incluso en el libro de texto...
Una construcción del tipo {algo, algo más} sólo puede ser una matriz de constantes. Pero allí se sustituyen los parámetros pasados a la función que en realidad son variables locales de la función. El modificador const en este caso no tiene ningún significado ya que sólo indica que el valor pasado no puede ser modificado. Como resultado
{fc_ColorSendBuy, fc_ColorSendSell}
es una expresión variable que el compilador no puede entender. Ay.
Para iniciar sesión y usar el sitio web MQL5.com es necesario permitir el uso de Сookies.
Por favor, active este ajuste en su navegador, de lo contrario, no podrá iniciar sesión.
Ha iniciado sesión. La autenticación de dos factores se ha desactivado. Vuelva a configurarla y escanee un nuevo código QR, o continúe con la autenticación de dos factores desactivada.
los nombres de los parámetros no son importantes... los diferentes nombres tienen sentido para que no se confunda algo con algo...
Puede escribir algunos valores en la declaración de la función,
y otros valores en la propia función
o puede nombrar los parámetros de forma idéntica en todas partes, lo que sea más conveniente para el escritor de código
En el mismo libro de texto, el código apareció:
Es extraño lo del constructor:
¿Por qué hay un operador de retorno aquí?Es la primera vez que veo que se utiliza este operador en el constructor. De hecho, el constructor se llama automáticamente. Y habrá una salida de todos modos. ¿Tiene sentido este operador en el constructor?
En el mismo libro de texto, el código apareció:
Es extraño lo del constructor:
¿Por qué hay un operador de retorno aquí?Es la primera vez que veo que se utiliza este operador en el constructor. De hecho, el constructor se llama automáticamente. Y habrá una salida de todos modos. ¿Tiene sentido este operador en el constructor?
No es necesario en este ejemplo, pero puede haber una inicialización compleja cuando se necesita una salida temprana.
El constructor y el destructor son funciones normales. Sólo el constructor y el destructor por defecto son llamados automáticamente. Los demás son llamados por el usuario.
El libro de texto da este ejemplo en relación con el polimorfismo:
Hay una cosa que no entiendo. Si utilizamos objetos de función hijos para las llamadas, es decir, los métodos derivados CCircle y CSquare, entonces el área de GetArea() puede ser calculada saltándose las declaraciones en la clase base. Es decir, no crear funciones virtuales en la clase base en absoluto, y en los métodos derivados crear un método simple y ya está. Entonces, ¿por qué necesitamos una función virtual?
Es interesante ver un ejemplo adecuado y lógico, en el que se puede ver que las funciones virtuales aportan algún beneficio. Porque lo que vi no era lógico, al menos para mí. Me gustaría entenderlo igualmente.
El libro de texto da este ejemplo en relación con el polimorfismo:
Hay una cosa que no entiendo. Si utilizamos objetos de función hijos para las llamadas, es decir, los métodos derivados CCircle y CSquare, entonces el área de GetArea() puede ser calculada saltándose las declaraciones en la clase base. Es decir, no crear funciones virtuales en una clase base en absoluto, y en los métodos derivados crear un método simple y ya está. Entonces, ¿por qué necesitamos una función virtual?
Es interesante ver un ejemplo adecuado y lógico, en el que se ve que las funciones virtuales aportan algún beneficio. Porque lo que vi no era lógico, al menos para mí. Me gustaría entenderlo igualmente.
Esta es la muestra más sencilla para entender el polimorfismo. Para conseguirlo rápidamente.
Hay casos complicados. Lo aplicará cuando lo necesite. No tiene sentido molestarse ahora. Cuando la tarea esté hecha, tendrás que pensar en ella.
Por ejemplo, tengo una clase base con todas las interfaces de lectura/escritura posibles. También tiene métodos virtuales privados (2 en total - lectura/escritura), que vinculan esta interfaz en la clase base con las clases derivadas. En realidad las clases derivadas pueden ser cualquiera donde haya trabajo con archivos (archivos, mapeo, canales, internet). Cada una de las clases derivadas define estos métodos virtuales de forma diferente, pero todas las clases tienen la misma interfaz de la clase base.
El libro de texto da este ejemplo en relación con el polimorfismo:
Hay una cosa que no entiendo. Si utilizamos los objetos de la función hija para las llamadas, es decir, los métodos derivados CCircle y CSquare, entonces el área de GetArea() se puede calcular omitiendo las declaraciones en la clase base. Es decir, no crear funciones virtuales en la clase base en absoluto, y en los métodos derivados crear un método simple y ya está. Entonces, ¿por qué necesitamos una función virtual?
Es interesante ver un ejemplo adecuado y lógico, en el que se ve que las funciones virtuales aportan algún beneficio. Porque lo que vi no era lógico, al menos para mí. Quiero entenderlo igualmente.
Intentaré esbozar una pequeña muestra:
Gracias a esta estructura, no necesitaremos entrar en el algoritmo de trabajo, que puede ser muy grande y complejo (todo está simplificado aquí), sólo tendremos que añadir un descendiente más, m3 en la enumeración y un caso más en el interruptor. Es decir, hemos unificado los datos de entrada, lo que evitará la edición en la parte principal del programa.
Por supuesto, esto sólo será apropiado si el algoritmo de trabajo acepta una variedad de tipos como entrada. Si sólo hay un tipo, todo esto es inútil.
El libro de texto da este ejemplo en relación con el polimorfismo:
Hay una cosa que no entiendo. Si utilizamos objetos de función hijos para las llamadas, es decir, los métodos derivados CCircle y CSquare, entonces el área de GetArea() puede ser calculada saltándose las declaraciones en la clase base. Es decir, no crear funciones virtuales en una clase base en absoluto, y en los métodos derivados crear un método simple y ya está. Entonces, ¿por qué necesitamos una función virtual?
Es interesante ver un ejemplo adecuado y lógico, en el que se puede ver que las funciones virtuales aportan algún beneficio. Porque lo que vi no era lógico, al menos para mí. Me gustaría entenderlo igualmente.
He aquí un ejemplo sencillo:
CShape* GetNewShape() { if( ... ) // Здесь какое-то условие. return new CCircle(); else return new CSquare(); } CShape* M[10]; for( int i = 0; i < 10; i++ ) { M[i] = GetNewShape(); } double WholeArea = 0.0; for( int i = 0; i < 10; i++ ) { WholeArea += M[i].GetArea(); }Utilizamos la función GetArea() sin saber a qué forma se llama.Tengo este colocador en una clase:
El compilador generalmente está luchando contra esta asignación de elementos a la matriz ColorBySend así:
'fc_ColorSendBuy' - constant expression required TradingFunc.mqh 91 23 'fc_ColorSendSell' - constant expression required TradingFunc.mqh 91 40 '{' - expression expected TradingFunc.mqh 91 22¿Qué tiene esto que ver? ¿Es realmente necesario asignar valores elemento por elemento? ¿No es posible hacerlo como una lista? ¿Con qué está relacionado? Después de todo, así es como funciona la tarea incluso en el libro de texto...Tengo este colocador en una clase:
El compilador jura esta asignación de elementos al array ColorBySend en general así:
¿Qué tiene esto que ver? ¿Es realmente necesario asignar valores elemento por elemento? ¿No es posible hacerlo como una lista? ¿Qué tiene que ver? Después de todo, así es como se hace la asignación incluso en el libro de texto...{fc_ColorSendBuy, fc_ColorSendSell}es una expresión variable que el compilador no puede entender. Ay.