1. La fonctionnalité descendante n'est pas disponible. Je ne sais pas qui ou comment, mais personnellement je n'ai jamais eu accès à SetRadius() et SetSide() à partir de l'Array.Peut-être y a-t-il un moyen de résoudre le problème avec autogenous, mais je veux m'en passer.
2. Peut-être que je ne travaille pas correctement avec les pointeurs, mais soit j'ai tout le temps une fuite, soit je dois frapper les pointeurs directement dans le bloc où le travail principal est effectué.
Tout ce qui est disponible... mon message ci-dessus
C'est juste que l'exemple que j'ai donné est tiré de la documentation et qu'il n'est pas clair comment cela devrait fonctionner...
Voici comment cela fonctionne. Mais complètement hors de la documentation :/ (Mais une fois de plus, je me suis exercé sur les pointeurs)
#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());
}
peut être fait beaucoup plus simplement... la virtualisation :
Ce n'est pas de ça que je parle. Il ne s'agit pas d'utiliser simplement des pointeurs, mais un tableau de ces pointeurs avec un type de classe de base.
CShape ArrShapes[10]; // массив объектов CShape
Peu importe qu'il s'agisse d'un simple tableau ou d'un tableau de pointeurs, seul ce qui est écrit dans la classe de base fonctionne et est disponible.
Ou peut-être que je rate quelque chose.
Par exemple, une classe de base légèrement modifiée (conçue comme une structure)
//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 nous entassons tous ces éléments dans le tableau, nous aurons accès au moins aux fonctionnalités déclarées dans la classe de base.
La question est de savoir comment accéder à la fonctionnalité par descendant si le tableau est de type classe de base (c'est-à-dire que le tableau est de type CShape) ?
Все объекты в MQL5 по умолчанию передаются по ссылке, но есть возможность использовать и указатели объектов. При этом есть опасность получить в качестве параметра функции указатель неинициализированного объекта. В этом случае работа программы будет завершена критически с последующей выгрузкой. Автоматически создаваемые объекты как правило такой ошибки не вызывают, и в этом отношении они достаточно безопасны. В этой статье мы попробуем разобраться в чем разница между ссылкой и указателей, когда оправдано использование указателей и как написать безопасный код с использованием указателей.
ce n'est pas ce dont je parle. Il ne s'agit pas d'utiliser simplement des pointeurs, mais un tableau de ces pointeurs avec un type de classe de base.
La question est de savoir comment accéder à la fonctionnalité par un descendant si le tableau est de type classe de base (c'est-à-dire que le tableau est de type CShape) ?
J'ai écrit sur la dernière page comment :
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;
}
C'est comme ça que ça marche. Mais complètement en dehors de la documentation :/
Eh bien, je veux dire la même chose, vous devriez au moins désigner toutes les fonctions dans une classe de base (sinon elles ne seront pas accessibles).
devrait être arraché avec la confiscation du clavier.
En C++, vous pouvez vous déplacer dans la hiérarchie des classes avec dynamic_cast, ce qui n'est pas apprécié là non plus. Dans MQL, cela peut provoquer des plantages implicites qui ne peuvent pas être facilement résolus, car le bogue se trouve à un endroit complètement différent.
Par conséquent, je déconseille fortement l'utilisation de ce type de conversion. C'est-à-dire, du tout. Aux ancêtres s'il vous plaît, aux enfants ni.
vous devriez enlever vos mains et vous faire confisquer votre clavier.
En C++, vous pouvez vous déplacer dans la hiérarchie des classes en utilisant dynamic_cast, et ce n'est pas apprécié là non plus. Dans MQL, cela peut provoquer des plantages implicites qui ne peuvent pas être facilement résolus, car le bogue se trouve à un endroit complètement différent.
Par conséquent, je déconseille catégoriquement l'utilisation d'une telle conversion. C'est-à-dire, pas du tout. Aux ancêtres s'il vous plaît, pas aux enfants.
Quelle est la façon polie de répondre....
Si le programmeur est trop bête, alors une simple opération 1+1 peut provoquer des plantages implicites.....
Et je tiens à souligner que MQL5 n'est pas C++...
C'est juste une possibilité, pas une question d'application.....
1. Supprimez m_radius() de l'ancêtre, il n'est pas dans l'exemple. :) Et vous n'obtiendrez aucun résultat avec elle dans OnStart() ;
2. la ligne "delete Base[0]" peut-elle être déplacée ailleurs ? Par exemple, si ce n'est pas un script mais un hibou et que j'ai toujours besoin des données dans le tableau.
J'ai eu des fuites de mémoire tout de suite. J'ai dû passer aux structures pour cette raison...
1. Supprimez m_radius(), il n'est pas présent dans l'exemple. Et on ne peut pas l'utiliser dans OnStart() ;
2. Puis-je déplacer la ligne de suppression Base[0] ailleurs ? Disons que ce n'est pas un script mais un hibou, et que j'ai toujours besoin des données dans le tableau.
J'ai eu une fuite de mémoire tout de suite. J'ai dû passer aux structures pour cette raison...
1) Enlevé, il fonctionne :
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) L'essentiel est de le supprimer avant la fin du programme... Mais si vous avez créé ce pointeur dans une fonction, vous devez prendre soin de le sauvegarder dans un endroit global...
1. La fonctionnalité descendante n'est pas disponible. Je ne sais pas qui ou comment, mais personnellement je n'ai jamais eu accès à SetRadius() et SetSide() à partir de l'Array.Peut-être y a-t-il un moyen de résoudre le problème avec autogenous, mais je veux m'en passer.
2. Peut-être que je ne travaille pas correctement avec les pointeurs, mais soit j'ai tout le temps une fuite, soit je dois frapper les pointeurs directement dans le bloc où le travail principal est effectué.
Je peux vous donner un exemple ?
C'est juste que l'exemple que j'ai donné est tiré de la documentation et qu'il n'est pas clair comment cela devrait fonctionner...
Voici comment cela fonctionne. Mais complètement hors de la documentation :/ (Mais une fois de plus, je me suis exercé sur les pointeurs)
Exécuter :
peut être fait beaucoup plus simplement... la virtualisation :
Ce n'est pas de ça que je parle. Il ne s'agit pas d'utiliser simplement des pointeurs, mais un tableau de ces pointeurs avec un type de classe de base.
Peu importe qu'il s'agisse d'un simple tableau ou d'un tableau de pointeurs, seul ce qui est écrit dans la classe de base fonctionne et est disponible.
Ou peut-être que je rate quelque chose.
Par exemple, une classe de base légèrement modifiée (conçue comme une structure)
Si nous entassons tous ces éléments dans le tableau, nous aurons accès au moins aux fonctionnalités déclarées dans la classe de base.
La question est de savoir comment accéder à la fonctionnalité par descendant si le tableau est de type classe de base (c'est-à-dire que le tableau est de type CShape) ?
ce n'est pas ce dont je parle. Il ne s'agit pas d'utiliser simplement des pointeurs, mais un tableau de ces pointeurs avec un type de classe de base.
La question est de savoir comment accéder à la fonctionnalité par un descendant si le tableau est de type classe de base (c'est-à-dire que le tableau est de type CShape) ?J'ai écrit sur la dernière page comment :
Même code, mais avec un tableau :
C'est comme ça que ça marche. Mais complètement en dehors de la documentation :/
Exécuter :
Pour quelque chose comme ça :
devrait être arraché avec la confiscation du clavier.
En C++, vous pouvez vous déplacer dans la hiérarchie des classes avec dynamic_cast, ce qui n'est pas apprécié là non plus. Dans MQL, cela peut provoquer des plantages implicites qui ne peuvent pas être facilement résolus, car le bogue se trouve à un endroit complètement différent.
Par conséquent, je déconseille fortement l'utilisation de ce type de conversion. C'est-à-dire, du tout. Aux ancêtres s'il vous plaît, aux enfants ni.
Pour quelque chose comme ça :
vous devriez enlever vos mains et vous faire confisquer votre clavier.
En C++, vous pouvez vous déplacer dans la hiérarchie des classes en utilisant dynamic_cast, et ce n'est pas apprécié là non plus. Dans MQL, cela peut provoquer des plantages implicites qui ne peuvent pas être facilement résolus, car le bogue se trouve à un endroit complètement différent.
Par conséquent, je déconseille catégoriquement l'utilisation d'une telle conversion. C'est-à-dire, pas du tout. Aux ancêtres s'il vous plaît, pas aux enfants.
Quelle est la façon polie de répondre....
Si le programmeur est trop bête, alors une simple opération 1+1 peut provoquer des plantages implicites.....
Et je tiens à souligner que MQL5 n'est pas C++...
C'est juste une possibilité, pas une question d'application.....
Même code, mais avec un tableau :
1. Supprimez m_radius() de l'ancêtre, il n'est pas dans l'exemple. :) Et vous n'obtiendrez aucun résultat avec elle dans OnStart() ;
2. la ligne "delete Base[0]" peut-elle être déplacée ailleurs ? Par exemple, si ce n'est pas un script mais un hibou et que j'ai toujours besoin des données dans le tableau.
J'ai eu des fuites de mémoire tout de suite. J'ai dû passer aux structures pour cette raison...
1. Supprimez m_radius(), il n'est pas présent dans l'exemple. Et on ne peut pas l'utiliser dans OnStart() ;
2. Puis-je déplacer la ligne de suppression Base[0] ailleurs ? Disons que ce n'est pas un script mais un hibou, et que j'ai toujours besoin des données dans le tableau.
J'ai eu une fuite de mémoire tout de suite. J'ai dû passer aux structures pour cette raison...
1) Enlevé, il fonctionne :
2) L'essentiel est de le supprimer avant la fin du programme... Mais si vous avez créé ce pointeur dans une fonction, vous devez prendre soin de le sauvegarder dans un endroit global...