1. Die Funktionalität der Nachkommenschaft ist nicht verfügbar. Ich weiß nicht, wer oder wie, aber ich persönlich habe nie Zugriff auf SetRadius() und SetSide() aus dem Array.Vielleicht gibt es einen Weg, um das Problem mit Autogenous zu lösen, aber ich möchte ohne sie zu tun.
2. Vielleicht arbeite ich falsch mit Zeigern, aber ich habe entweder immer ein Leck oder muss die Zeiger genau in dem Block treffen, in dem die Hauptarbeit geleistet wird.
Es ist nur so, dass das Beispiel, das ich gegeben habe, aus der Dokumentation stammt und es nicht klar ist, wie es funktionieren soll...
Das funktioniert folgendermaßen. Aber völlig aus der Dokumentation :/ (Aber ich habe wieder einmal mit Zeigern geübt)
#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());
}
kann viel einfacher gemacht werden... Virtualisierung:
Das ist nicht das, was ich meine. Es geht nicht nur um die Verwendung von Zeigern, sondern um ein Array von Zeigern mit einem Basisklassentyp.
CShape ArrShapes[10]; // массив объектов CShape
Es spielt keine Rolle, ob es sich um ein einfaches Array oder ein Array mit Zeigern handelt, es funktioniert nur das, was in der Basisklasse steht.
Oder vielleicht übersehe ich etwas.
Zum Beispiel eine leicht veränderte Basisklasse (als Struktur konzipiert)
//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); }// возвращает площадь фигуры
};
Wenn wir all diese Dinge in das Array packen, haben wir zumindest Zugriff auf die in der Basisklasse deklarierten Funktionen.
Die Frage ist, wie der Zugriff auf Funktionalität durch Nachkomme, wenn das Array der Basisklasse Typ ist (d.h. Array ist von CShape Typ)?
Все объекты в MQL5 по умолчанию передаются по ссылке, но есть возможность использовать и указатели объектов. При этом есть опасность получить в качестве параметра функции указатель неинициализированного объекта. В этом случае работа программы будет завершена критически с последующей выгрузкой. Автоматически создаваемые объекты как правило такой ошибки не вызывают, и в этом отношении они достаточно безопасны. В этой статье мы попробуем разобраться в чем разница между ссылкой и указателей, когда оправдано использование указателей и как написать безопасный код с использованием указателей.
Das ist nicht das, wovon ich spreche. Es geht nicht um die einfache Verwendung von Zeigern, sondern um ein Array dieser Zeiger mit einem Basisklassentyp.
Die Frage ist, wie man auf die Funktionalität durch einen Nachkommen zugreifen kann, wenn das Array vom Typ der Basisklasse ist (d.h. das Array ist vom Typ CShape)?
Ich habe auf der letzten Seite geschrieben, wie:
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;
}
sollte mit der Beschlagnahmung der Tastatur aufgehoben werden.
In C++ kann man sich mit dynamic_cast durch die Klassenhierarchie bewegen, und auch dort ist es nicht beliebt. In MQL kann es zu impliziten Abstürzen kommen, die nicht leicht zu beheben sind, weil der Fehler an einer ganz anderen Stelle liegt.
Daher rate ich dringend davon ab, diese Art der Umwandlung zu verwenden. Das heißt, überhaupt nicht. Für die Vorfahren bitte, für die Kinder ni.
sollte man Ihnen die Hände abnehmen und die Tastatur konfiszieren.
In C++ können Sie sich mit dynamic_cast durch die Klassenhierarchie bewegen, und auch dort ist es nicht beliebt. In MQL kann es zu impliziten Abstürzen kommen, die nicht leicht zu beheben sind, weil der Fehler an einer ganz anderen Stelle liegt.
Daher rate ich kategorisch davon ab, eine solche Umwandlung vorzunehmen. Das heißt, ganz und gar nicht. An die Vorfahren bitte, nicht an die Kinder.
Wie lautet die höfliche Antwort an....
Wenn der Programmierer zu dumm ist, dann kann eine einfache 1+1-Operation zu impliziten Abstürzen führen....
Und ich möchte darauf hinweisen, dass MQL5 nicht C++ ist...
Dies ist nur eine Möglichkeit, keine Frage der Bewerbung....
1. Entfernen Sie m_radius() aus dem Vorgänger, es ist nicht im Beispiel enthalten. :) Und Sie werden in OnStart() keine Arbeit damit haben;
2. Kann die Zeile delete Base[0] an eine andere Stelle verschoben werden? Nehmen wir an, es handelt sich nicht um ein Skript, sondern um eine Eule, und ich benötige trotzdem die Daten im Array.
Ich habe sofort Speicherlecks. Aus diesem Grund musste ich zu Strukturen wechseln...
1. Entfernen Sie m_radius(), es ist in dem Beispiel nicht vorhanden. Und in OnStart() keine Arbeit damit bekommen;
2. Kann ich die Zeile delete Base[0] an eine andere Stelle verschieben? Nehmen wir an, es handelt sich nicht um ein Skript, sondern um eine Eule, und ich benötige trotzdem die Daten im Array.
Ich habe sofort ein Speicherleck. Aus diesem Grund musste ich zu Strukturen wechseln...
1) Entfernt, es funktioniert:
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) Das Wichtigste ist, sie zu löschen, bevor das Programm endet... Wenn Sie diesen Zeiger jedoch in einer Funktion erstellt haben, müssen Sie dafür sorgen, dass er an einem globalen Ort gespeichert wird...
1. Die Funktionalität der Nachkommenschaft ist nicht verfügbar. Ich weiß nicht, wer oder wie, aber ich persönlich habe nie Zugriff auf SetRadius() und SetSide() aus dem Array.Vielleicht gibt es einen Weg, um das Problem mit Autogenous zu lösen, aber ich möchte ohne sie zu tun.
2. Vielleicht arbeite ich falsch mit Zeigern, aber ich habe entweder immer ein Leck oder muss die Zeiger genau in dem Block treffen, in dem die Hauptarbeit geleistet wird.
Darf ich Ihnen ein Beispiel nennen?
Es ist nur so, dass das Beispiel, das ich gegeben habe, aus der Dokumentation stammt und es nicht klar ist, wie es funktionieren soll...
Das funktioniert folgendermaßen. Aber völlig aus der Dokumentation :/ (Aber ich habe wieder einmal mit Zeigern geübt)
Ausführen:
kann viel einfacher gemacht werden... Virtualisierung:
Das ist nicht das, was ich meine. Es geht nicht nur um die Verwendung von Zeigern, sondern um ein Array von Zeigern mit einem Basisklassentyp.
Es spielt keine Rolle, ob es sich um ein einfaches Array oder ein Array mit Zeigern handelt, es funktioniert nur das, was in der Basisklasse steht.
Oder vielleicht übersehe ich etwas.
Zum Beispiel eine leicht veränderte Basisklasse (als Struktur konzipiert)
Wenn wir all diese Dinge in das Array packen, haben wir zumindest Zugriff auf die in der Basisklasse deklarierten Funktionen.
Die Frage ist, wie der Zugriff auf Funktionalität durch Nachkomme, wenn das Array der Basisklasse Typ ist (d.h. Array ist von CShape Typ)?
Das ist nicht das, wovon ich spreche. Es geht nicht um die einfache Verwendung von Zeigern, sondern um ein Array dieser Zeiger mit einem Basisklassentyp.
Die Frage ist, wie man auf die Funktionalität durch einen Nachkommen zugreifen kann, wenn das Array vom Typ der Basisklasse ist (d.h. das Array ist vom Typ CShape)?Ich habe auf der letzten Seite geschrieben, wie:
Gleicher Code, nur mit einem Array:
So funktioniert es. Aber völlig abseits der Dokumentation :/
Ausführen:
Für etwas wie dieses:
sollte mit der Beschlagnahmung der Tastatur aufgehoben werden.
In C++ kann man sich mit dynamic_cast durch die Klassenhierarchie bewegen, und auch dort ist es nicht beliebt. In MQL kann es zu impliziten Abstürzen kommen, die nicht leicht zu beheben sind, weil der Fehler an einer ganz anderen Stelle liegt.
Daher rate ich dringend davon ab, diese Art der Umwandlung zu verwenden. Das heißt, überhaupt nicht. Für die Vorfahren bitte, für die Kinder ni.
Für etwas wie dieses:
sollte man Ihnen die Hände abnehmen und die Tastatur konfiszieren.
In C++ können Sie sich mit dynamic_cast durch die Klassenhierarchie bewegen, und auch dort ist es nicht beliebt. In MQL kann es zu impliziten Abstürzen kommen, die nicht leicht zu beheben sind, weil der Fehler an einer ganz anderen Stelle liegt.
Daher rate ich kategorisch davon ab, eine solche Umwandlung vorzunehmen. Das heißt, ganz und gar nicht. An die Vorfahren bitte, nicht an die Kinder.
Wie lautet die höfliche Antwort an....
Wenn der Programmierer zu dumm ist, dann kann eine einfache 1+1-Operation zu impliziten Abstürzen führen....
Und ich möchte darauf hinweisen, dass MQL5 nicht C++ ist...
Dies ist nur eine Möglichkeit, keine Frage der Bewerbung....
Gleicher Code, nur mit einem Array:
1. Entfernen Sie m_radius() aus dem Vorgänger, es ist nicht im Beispiel enthalten. :) Und Sie werden in OnStart() keine Arbeit damit haben;
2. Kann die Zeile delete Base[0] an eine andere Stelle verschoben werden? Nehmen wir an, es handelt sich nicht um ein Skript, sondern um eine Eule, und ich benötige trotzdem die Daten im Array.
Ich habe sofort Speicherlecks. Aus diesem Grund musste ich zu Strukturen wechseln...
1. Entfernen Sie m_radius(), es ist in dem Beispiel nicht vorhanden. Und in OnStart() keine Arbeit damit bekommen;
2. Kann ich die Zeile delete Base[0] an eine andere Stelle verschieben? Nehmen wir an, es handelt sich nicht um ein Skript, sondern um eine Eule, und ich benötige trotzdem die Daten im Array.
Ich habe sofort ein Speicherleck. Aus diesem Grund musste ich zu Strukturen wechseln...
1) Entfernt, es funktioniert:
2) Das Wichtigste ist, sie zu löschen, bevor das Programm endet... Wenn Sie diesen Zeiger jedoch in einer Funktion erstellt haben, müssen Sie dafür sorgen, dass er an einem globalen Ort gespeichert wird...