Fehler, Irrtümer, Fragen - Seite 2471

 
Igor Makanu:

Erklären Sie, warum ich beim Erstellen von CChartObjectLabel die Objekte im Indikator nicht lösche, wenn ich in diesem Code deinitialisiere:

beim TF-Wechsel erhalte ich einen Journaleintrag: 2019.05.23 09:49:02.044 tstlabel EURUSD,M30: 2 Objekte vom Typ CChartObjectLabel übrig

wenn in OnInit() die Erstellung von Textbeschriftungen (CChartObjectLabel) auskommentiert wird, dann funktioniert alles korrekt

Ich übergebe einen Zeiger an die FunktionCreateLabel(), aberich kannihn später inOnDeinit() nichtlöschen

Es wird ein neues Objekt l erstellt. Und sie wird nicht gelöscht.
 
Artyom Trishkin:
Ein neues l-Objekt wird erstellt. Und sie wird nicht gelöscht.

logischerweise

Aber der Geltungsbereich vonCChartObjectLabel *LabelUP,*LabelDN; Variablen ist global?

Ich kann also die Variable an jeder Stelle des Codes ändern?

Ich übergebe einen Zeiger an die Funktion CreateLabel(), warum erzeuge ich eine neue Kopie?

Imho funktioniert es nicht richtig.

HH: Wenn ich Objekte in OnInit() erzeuge und dann mit ihnen in CreateLabel() arbeite (d.h. ich erzeuge die Objekte separat und arbeite mit ihnen per Zeiger), funktioniert alles korrekt - aber ich kann mich nicht an einen Fall in anderen Compilern erinnern, in dem ein Zeiger an eine Funktion übergeben wurde, um ein neues Objekt zu erzeugen - ein Zeiger, er ist ein Zeiger!

 
Igor Makanu:

logischerweise

aber mein Geltungsbereich ist global? - bedeutet das, dass ich eine Variable in jedem Teil meines Codes ändern kann?

Ich übergebe einen Zeiger an CreateLabel(), warum erhalte ich eine neue Kopie?

Imho funktioniert das nicht richtig.

Durch die Neuzuweisung eines Zeigers an ein neues Objekt geht das vorherige Objekt, auf das der neu zugewiesene Zeiger zeigte, verloren.
 
Igor Makanu:

logischerweise

Aber der Geltungsbereich vonCChartObjectLabel *LabelUP,*LabelDN; Variablen ist global?

Ich kann also die Variable an jeder Stelle des Codes ändern?

Ich übergebe einen Zeiger an die Funktion CreateLabel(), warum erzeuge ich eine neue Kopie?

Imho funktioniert es nicht richtig

muss entfernt werden. Es gibt bereits Objekte und Zeiger auf sie.
 
Artyom Trishkin:
Wenn wir einen Zeiger einem neuen Objekt zuweisen, verlieren wir das vorherige Objekt, auf das der neu zugewiesene Zeiger zeigte.

nein, ein Zeiger ist ein Zeiger, in MQL ist es ein Deskriptor, nicht der Punkt - aber es ist nicht korrekt, eine neue Kopie des Objekts zu erstellen, dies funktioniert jetzt korrekt:

//+------------------------------------------------------------------+
//|                                                         test.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#property strict
#property indicator_separate_window
#include <ChartObjects\ChartObjectsTxtControls.mqh>
CChartObjectLabel *LabelUP,*LabelDN;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   LabelUP=new CChartObjectLabel;
   LabelDN=new CChartObjectLabel;
   SetLabel(LabelUP,"LabelUP",0);
   SetLabel(LabelDN,"LabelDN",25);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   delete LabelUP;
   delete LabelDN;
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   return(rates_total);

  }
//+------------------------------------------------------------------+
void SetLabel(CChartObjectLabel *l,string name,int y)
  {
   l.Create(0,name,ChartWindowFind(),0,y);
   l.Color(clrYellow);
   l.FontSize(14);
   l.Description(name);
  }
//+------------------------------------------------------------------+

aber wenn Sie Ihrer Logik folgen, dann wird dieser Code auch eine Kopie des Objekts l in der Funktion SetLabel() erstellen - ich habe einen Zeiger übergeben, nicht eine Referenz?


Artyom Trishkin:
sollten entfernt werden. Die Objekte sind bereits vorhanden, ebenso wie die Zeiger auf sie.

die Frage ist nicht, wie das Problem zu lösen, aber warum in den globalen Geltungsbereich der VariablenCChartObjectLabel *LabelUP,*LabelDN;- verloren den Zeiger!

 
Igor Makanu:

nein, ein Zeiger ist ein Zeiger, in MQL ist es ein Deskriptor, nicht der Punkt - aber es ist nicht korrekt, eine neue Kopie des Objekts zu erstellen, dies funktioniert jetzt korrekt:

aber wenn Sie Ihrer Logik folgen, dann wird dieser Code auch eine Kopie von Objekt l in der Funktion SetLabel() erstellen - ich habe einen Zeiger übergeben, keine Referenz?

Nein. Hier ist l ein Parameter der Methode, über den wir den benötigten Zeiger übergeben. Hier ist alles in Ordnung. Der Zeiger bleibt hier auf dem zuvor erstellten Objekt. Hier wird kein neues Objekt erstellt und der Zeiger darauf neu zugewiesen, ohne dass das vorherige Objekt verloren geht.
 
Artyom Trishkin:
Nein. Hier ist l der Methodenparameter, über den wir den erforderlichen Zeiger übergeben. Hier ist alles in Ordnung. Der Zeiger bleibt hier auf dem zuvor erstellten Objekt. Hier wird kein neues Objekt erstellt und der Zeiger darauf neu zugewiesen, ohne dass das vorherige Objekt verloren geht.

es funktioniert immer noch nicht richtig

diese "Zeiger" in MQL sind dafür gemacht, im Bereich der Klasse zu arbeiten, ich möchte keine Klasse erstellen, ich deklariere einen globalen Zeiger und übergebe ihn dann an eine beliebige Funktion, und die Tatsache, dass ich in dieser Funktion einen Deskriptor des Objekts erstelle, ist nicht der Grund, das Objekt beim Verlassen des lokalen Bereichs der Funktion zu zerstören

Ich bin ein wenig beschäftigt im Moment, aber ich brauche, um Testbeispiele ohne Grafiken zu machen - ich denke, die gleiche Sache passieren wird, wenn Sie die Funktion mit einem Zeiger mit POINTER_INVALID Wert eingegeben, werden Sie mit dem gleichen POINTER_INVALID beenden, durch Verweis, alles wird richtig funktionieren, aber es scheint, Sie können nicht einen Zeiger mit POINTER_INVALID durch Verweis übergeben - es wird ein Fehler beim Zugriff auf den Zeiger sein

 
Igor Makanu:

sowieso nicht alles richtig funktioniert

diese "Zeiger" in MQL sind dafür gemacht, im Bereich der Klasse zu arbeiten, ich möchte keine Klasse erstellen, ich bohre einfach und deklariere einen Zeiger im globalen Bereich, dann übergebe ich ihn an eine beliebige Funktion und die Tatsache, dass ich einen Objektdeskriptor in dieser Funktion erstelle, ist nicht der Grund, das Objekt beim Verlassen des lokalen Bereichs der Funktion zu zerstören

Ich denke, es wird das gleiche Problem sein, wenn Sie in mit POINTER_INVALID Wert in dieser Funktion kommen, werden Sie mit dem gleichen POINTER_INVALID Wert verlassen, durch Verweis, wird alles richtig funktionieren, aber durch Verweis können Sie nicht einen Zeiger mit POINTER_INVALID übergeben - Zeigerzugriff Fehler auftreten wird.

Genau genommen wird das Objekt nicht zerstört. Nachdem ein neues Objekt innerhalb der Methode erstellt wurde, haben wir bereits zwei Objekte. Und es gibt nur einen Zeiger - er wurde der Methode als formaler Parameter übergeben. Dadurch verlieren wir den Zeiger auf eines der Objekte.
 

Ich war überrascht, dass es möglich war, typedef mit einem Zeiger auf eine Vorlagenfunktion zu deklarieren.
Die Freude währte jedoch nicht lange.

template<typename T>
typedef bool (* callback)(T &);

template<typename T>
bool ff(T &){
   return true;
}

bool ff(int &){
   return true;
}


void OnStart(){
   int a;
   ff(a);
   
   callback<int> f_ptr_0 = ff;     //'<' - unexpected token     
   callback f_ptr_1 = ff;          //'ff' - function must have a body   
   callback f_ptr_2 = ff<int>;     //'ff<int>' - cannot resolve function address  //'ff<int>' - type mismatch   
}


Ist typedef mit einem Zeiger auf eine Template-Funktion ein geplantes Feature?

 
Ein weiterer Fehler im typedef garden:
typedef void (* callback)(int &);

template<typename T>
void ff(T &){}


void OnStart(){
   int a = 0;
   //ff(a);                     //  если раскомментировать, то работает
   
   callback f_ptr = ff<int>;    //  'ff<int>' - function must have a body
   f_ptr(a);
}

Bei der Arbeit mit typedef wird bei der Verwendung einer Vorlagenfunktion mit expliziter Spezialisierung kein Code für diese Vorlage erzeugt