1. La funcionalidad de los descendientes no está disponible. No sé quién o cómo, pero personalmente nunca he conseguido acceder a SetRadius() y SetSide() desde el Array.Quizás haya una forma de solucionar el problema con autogenous, pero quiero prescindir de él.
2. Tal vez estoy trabajando incorrectamente con los punteros, pero o bien tengo una fuga todo el tiempo o tengo que golpear los punteros justo en el bloque donde se realiza el trabajo principal.
Es que el ejemplo que he puesto está sacado de la documentación y no está claro cómo debería funcionar...
Así es como funciona. Pero completamente sin documentación :/ (Pero una vez más he practicado con punteros)
#property copyright "Ya"#property link "Ya"#property version "1.00"//--- Базовый класс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);};// возвращает тип фигурыvirtualvoid SetRadius(double r){return;};
virtualvoid SetSide(double s){return;};
virtualdouble GetArea(){return(0); }// возвращает площадь фигуры
};
//--- производный класс Кругclass CCircle: public CShape // после двоеточия указывается базовый класс,
{ // от которого производится наследование private:
double m_radius; // радиус кругаpublic:
void CCircle(){m_type=1; m_radius=10;}; // конструктор, тип равен 1 virtualvoid 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 virtualvoid SetSide(double s){m_square_side=s;};
virtualdouble GetArea(){return(m_square_side*m_square_side);}//площадь квадрата
};
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnStart()
{
CCircle *ci=new CCircle;
CSquare *sq=new CSquare;
CShape *shapes[2]; // массив объектов CShape
shapes[0]=ci;
shapes[1]=sq;
////---зададим уникальные свойства объектов
shapes[0].SetRadius(5.0);
shapes[1].SetSide(4.0);
for(int i=0; i<2;i++)
{
//--- тип и площадь фигурыPrint("Объект типа "+shapes[i].GetType()+" имеет площадь "+shapes[i].GetArea());
}
puede hacerse de forma mucho más sencilla... virtualización:
No me refiero a eso. No estamos hablando de usar simplemente punteros, estamos hablando de un array de estos punteros con un tipo de clase base.
CShape ArrShapes[10]; // массив объектов CShape
No importa si es un simple array o un array de punteros, sólo lo que está escrito en la clase base funciona y está disponible.
O quizás me estoy perdiendo algo.
Por ejemplo, una clase base ligeramente modificada (diseñada como una estructura)
//class CShapestruct CShape
//Базовый класс
{
protected:
int m_type; // тип фигурыint m_xpos; // X - координата точки привязкиint m_ypos; // Y - координата точки привязкиpublic:
void CShape(){m_type=0;}; // конструктор, тип равен нулюint GetType(){return(m_type);};// возвращает тип фигурыvoid SetPosX(int s){m_xpos=s;};
int GetPosX(){return(m_xpos);};
void SetPosY(int s){m_ypos=s;};
int GetPosY(){return(m_ypos);};
double GetArea(){return (0); }// возвращает площадь фигуры
};
Si metemos todo esto en el array, tendremos acceso al menos a la funcionalidad declarada en la clase base.
La pregunta es cómo acceder a la funcionalidad por descendiente si el array es de tipo de clase base (es decir, el array es de tipo CShape).
Все объекты в MQL5 по умолчанию передаются по ссылке, но есть возможность использовать и указатели объектов. При этом есть опасность получить в качестве параметра функции указатель неинициализированного объекта. В этом случае работа программы будет завершена критически с последующей выгрузкой. Автоматически создаваемые объекты как правило такой ошибки не вызывают, и в этом отношении они достаточно безопасны. В этой статье мы попробуем разобраться в чем разница между ссылкой и указателей, когда оправдано использование указателей и как написать безопасный код с использованием указателей.
no es eso de lo que estoy hablando. No estamos hablando de usar simplemente punteros, sino de un array de estos punteros con un tipo de clase base.
La cuestión es cómo acceder a la funcionalidad por parte de un descendiente si el array es de tipo de clase base (es decir, el array es de tipo CShape).
He escrito en la última página cómo:
class CBase
{
public:
void m_radius() {Print("CBase");}
};
class CTest : public CBase
{
public:
void m_radius() {Print("CTest");}
};
CBase* Base;
voidOnStart()
{
Base = new CTest;
Base.m_radius();
((CTest *)Base).m_radius();
delete Base;
}
debería ser arrancado con la confiscación del teclado.
En C++ puedes moverte a través de la jerarquía de clases con dynamic_cast, y ahí tampoco te gusta. En MQL, puede provocar fallos implícitos que no se pueden resolver fácilmente, porque el fallo está en un lugar completamente diferente.
Por lo tanto, desaconsejo encarecidamente el uso de este tipo de conversión. Es decir, en absoluto. A los ancestros por favor, a los niños ni.
deberían quitarte las manos y confiscarte el teclado.
En C++, puedes moverte a través de la jerarquía de clases usando dynamic_cast, y tampoco te gusta allí. En MQL puede provocar fallos implícitos que no se pueden resolver fácilmente, porque el fallo está en un lugar completamente diferente.
Por lo tanto, desaconsejo categóricamente el uso de dicha conversión. Es decir, en absoluto. A los ancestros por favor, no a los niños.
¿Cuál es la forma educada de responder? ....
Si el programador es demasiado tonto, una simple operación de 1+1 puede provocar choques implícitos....
Y quiero señalar que MQL5 no es C++...
Esto es sólo una posibilidad, no una cuestión de aplicación....
1. Quita m_radio() del ancestro, no está en el ejemplo. :) Y no conseguirás trabajar con él en OnStart();
2. ¿se puede trasladar la línea de borrado de Base[0] a otro lugar? Digamos que si no es un script sino un búho y todavía necesito los datos del array.
Tengo fugas de memoria de inmediato. Tuve que cambiar a estructuras por esta razón...
class CBase
{
public:
};
class CTest : public CBase
{
public:
void m_radius() {Print("CTest");}
};
CBase* Base[1];
voidOnStart()
{
Base[0] = new CTest;
((CTest *)Base[0]).m_radius();
delete Base[0];
}
2) Lo principal es borrarlo antes de que termine el programa... Pero si tienes este puntero creado en una función, tienes que ocuparte de guardarlo en una ubicación global...
1. La funcionalidad de los descendientes no está disponible. No sé quién o cómo, pero personalmente nunca he conseguido acceder a SetRadius() y SetSide() desde el Array.Quizás haya una forma de solucionar el problema con autogenous, pero quiero prescindir de él.
2. Tal vez estoy trabajando incorrectamente con los punteros, pero o bien tengo una fuga todo el tiempo o tengo que golpear los punteros justo en el bloque donde se realiza el trabajo principal.
¿Puedo darle un ejemplo?
Es que el ejemplo que he puesto está sacado de la documentación y no está claro cómo debería funcionar...
Así es como funciona. Pero completamente sin documentación :/ (Pero una vez más he practicado con punteros)
Ejecutar:
puede hacerse de forma mucho más sencilla... virtualización:
No me refiero a eso. No estamos hablando de usar simplemente punteros, estamos hablando de un array de estos punteros con un tipo de clase base.
No importa si es un simple array o un array de punteros, sólo lo que está escrito en la clase base funciona y está disponible.
O quizás me estoy perdiendo algo.
Por ejemplo, una clase base ligeramente modificada (diseñada como una estructura)
Si metemos todo esto en el array, tendremos acceso al menos a la funcionalidad declarada en la clase base.
La pregunta es cómo acceder a la funcionalidad por descendiente si el array es de tipo de clase base (es decir, el array es de tipo CShape).
no es eso de lo que estoy hablando. No estamos hablando de usar simplemente punteros, sino de un array de estos punteros con un tipo de clase base.
La cuestión es cómo acceder a la funcionalidad por parte de un descendiente si el array es de tipo de clase base (es decir, el array es de tipo CShape).He escrito en la última página cómo:
El mismo código, sólo que con un array:
Así es como funciona. Pero completamente fuera de la documentación :/
Ejecutar:
Por algo así:
debería ser arrancado con la confiscación del teclado.
En C++ puedes moverte a través de la jerarquía de clases con dynamic_cast, y ahí tampoco te gusta. En MQL, puede provocar fallos implícitos que no se pueden resolver fácilmente, porque el fallo está en un lugar completamente diferente.
Por lo tanto, desaconsejo encarecidamente el uso de este tipo de conversión. Es decir, en absoluto. A los ancestros por favor, a los niños ni.
Por algo así:
deberían quitarte las manos y confiscarte el teclado.
En C++, puedes moverte a través de la jerarquía de clases usando dynamic_cast, y tampoco te gusta allí. En MQL puede provocar fallos implícitos que no se pueden resolver fácilmente, porque el fallo está en un lugar completamente diferente.
Por lo tanto, desaconsejo categóricamente el uso de dicha conversión. Es decir, en absoluto. A los ancestros por favor, no a los niños.
¿Cuál es la forma educada de responder? ....
Si el programador es demasiado tonto, una simple operación de 1+1 puede provocar choques implícitos....
Y quiero señalar que MQL5 no es C++...
Esto es sólo una posibilidad, no una cuestión de aplicación....
El mismo código, sólo que con un array:
1. Quita m_radio() del ancestro, no está en el ejemplo. :) Y no conseguirás trabajar con él en OnStart();
2. ¿se puede trasladar la línea de borrado de Base[0] a otro lugar? Digamos que si no es un script sino un búho y todavía necesito los datos del array.
Tengo fugas de memoria de inmediato. Tuve que cambiar a estructuras por esta razón...
1. Eliminar m_radio(), no está presente en el ejemplo. Y no se consigue trabajar con él en OnStart();
2. ¿puedo mover la línea de eliminación de Base[0] a otro lugar? Digamos que si no es un script sino un búho, y todavía necesito los datos del array.
Tengo una fuga de memoria de inmediato. Tuve que cambiar a estructuras por esta razón...
1) Eliminado, funciona:
2) Lo principal es borrarlo antes de que termine el programa... Pero si tienes este puntero creado en una función, tienes que ocuparte de guardarlo en una ubicación global...