Fragen zu OOP in MQL5 - Seite 83

 

Jaaa... Wie verkorkst die Leute sind mit const(((.

Zum Verständnis von Methoden mit const-Spezifizierer

class CTest{
   int i;
public:
   CTest(int _i):i(_i){}
   int Get() const {return i;}
   int Get()   {return 2*i;}
};

void OnStart()
  {
   const CTest a(5);
   CTest b(8);
   Print(a.Get()); //5
   Print(b.Get()); //16
  }

Jetzt tun

   //int Get() const {return i;}

und dann in umgekehrter Richtung:

//   int Get()   {return 2*i;}

)))

 
Alexandr Andreev:

Auch eine Variante desselben Codes.


Es ist mit den Konstanten.

Und Sie sind sicher, dass die Eingabe

Compare(CObject const *node,int const mode=0)

♪ Du wirst immer füttern ♪

CChartObjectRectangleX*

ohne Kontrolle zu schreiben?

return (  Time(1)-dynamic_cast<const ME*>(node).Time(1));

?

 
Alexandr Andreev:

die Variante ohne die Konstitution, da die Basisklasse keinen Bezug zu Eingabeparametern hat, wird ebenfalls korrekt funktionieren, obwohl dieser Stil nicht sehr clever ist

So wird es nicht funktionieren. Sie können die Signatur in Compare nicht ändern. Sie wird hauptsächlich für die QuickSort-Methode benötigt, die in SB enthalten ist, damit sie funktioniert.

Wenn Sie die Signatur ändern, handelt es sich nicht um eine Überschreibung einer virtuellen Funktion, sondern um eine Überladung, und es wird eine Methode der Basisklasse CObject aufgerufen, die 0 zurückgibt;

Natürlich kann dies durch Wrapper (Dekoration) zu Containern gelöst werden, aber warum diese unnötigen Bewegungen, oder sonst nicht verwenden SB und schreiben alles von Grund auf neu.

 
Vladimir Simakov:

Es scheint dasselbe zu sein wie bei Ihnen, nur mit weniger Buchstaben. Es ist also Geschmackssache, aber ich habe die zusätzliche Variable entfernt (höchstwahrscheinlich hätte der Compiler sie im Rahmen der Optimierung entfernt).

Bezüglich meines !node-Checks. Er muss durch CheckPointer(node)==POINTER_INVALID ersetzt werden, aber das ist ein Overhead - ein Funktionsaufruf. Selbst wenn es inlined ist, wird zumindest das Statusflag dereferenziert und überprüft. Wenn nur Bibliothek oder konkrete, Sie geschrieben haben Programm wird Compare-Methoden verwenden, besser !node und auf Code für ungültige Zeiger zu beobachten. Wenn Sie zu faul sind, auf Zeiger zu achten, oder es sich um eine Bibliothek für Außenseiter handelt, ist nur CheckPointer(node)==POINTER_INVALID möglich.

Wenn Sie den hervorgehobenen const-Spezifizierer entfernen, können Sie diese Methoden nicht von einem konstanten Objekt aus aufrufen.

UPD: Die hervorgehobene Prüfung kann entfernt werden, da sie in den aufgerufenen Methoden enthalten ist.

Vladimir, gerade in diesem Fall ist CheckPointer überflüssig. dynamic_cast gibt bei jedem fehlgeschlagenen Cast NULL zurück, auch wenn der Zeiger kaputt ist. Bitte korrigieren Sie mich, wenn ich falsch liege. Vor langer Zeit getestet, dauerte der Test 5 Sekunden).

Mechanismus der CheckPointer arbeiten (in einfachen Worten, ich bin nicht fließend in Low-Level-Begriffe) - es sieht durch Zeiger, welche Art von Objekt, dynamisch oder statisch, wenn wir nicht bekommen können Informationen, es bedeutet POINTER_INVALID. Dies kann der Fall sein, wenn das dynamische Objekt entfernt wurde, andere Situationen, die ich nicht kenne, oder hochgeladen Müll auf den Zeiger, aber es muss der Compiler zu überprüfen, wenn Sie nicht finden können, Schlupflöcher.

und dynamic_cast tut dasselbe, wobei zusätzlich geprüft wird, ob der Zeiger in den gewünschten Typ gecastet werden kann, d. h. ob es sich um einen Zeiger dieses Typs oder einer Unterklasse handelt.

Wenn der Zeiger defekt ist, kann dynamic_cast nichts erkennen und gibt NULL zurück.

Aus diesem Grund habe ich CheckPointer nicht verwendet. Aber ich benutze diesen Scheck in der Regel überall, wo ich nicht in Gefahr bin. Immerhin, einen Fehler in einer Software zu finden, die nicht heruntergefallen ist, scheint ein wenig einfacher zu sein).

Und was ist mit non-const - theoretisch können wir eine Methode wie GetRatingByAnyFormula() { m_rating01=Formula01(); return m_rating01;} haben.

wäre recht umständlich, wenn sie nicht gleich bei der Sortierung verwendet würde, d.h. wir müssten erst die Bewertung zählen und dann die Sortierung nach ihr aufrufen. Oder, wie bereits gesagt, schreiben Sie Ihr eigenes SB von Grund auf).

 
Aleksey Mavrin:

Das ist nicht gut. Die Signatur kann in Compare nicht geändert werden. Sie dient hauptsächlich dem Zweck, QuickSort, die reguläre Sortiermethode in SB, zum Laufen zu bringen.

Wenn Sie die Signatur ändern, wird die virtuelle Funktion nicht überschrieben, sondern überladen und die Methode der Basisklasse CObject wird aufgerufen, wobei 0 zurückgegeben wird;

Natürlich kann dies durch Wrapper (Dekoration) zu Containern gelöst werden, aber warum diese unnötigen Bewegungen, oder verwenden Sie nicht SB und schreiben alles von Grund auf neu?

Der korrekteste Weg ist, nicht auf µl zu schreiben.

 
Aleksey Mavrin:

Vladimir, in diesem Fall ist CheckPointer überflüssig. dynamic_cast gibt bei jedem erfolglosen Cast NULL zurück, auch wenn der Zeiger kaputt ist. Bitte korrigieren Sie mich, wenn ich falsch liege. Vor langer Zeit getestet, dauerte der Test 5 Sekunden).

Mechanismus der CheckPointer arbeiten (in einfachen Worten, ich bin nicht fließend in Low-Level-Begriffe) - es sieht durch Zeiger, welche Art von Objekt, dynamisch oder statisch, wenn wir nicht bekommen können Informationen, es bedeutet POINTER_INVALID. Dies kann der Fall sein, wenn das dynamische Objekt entfernt wurde, andere Situationen, die ich nicht kenne, oder hochgeladen Müll auf den Zeiger, aber es muss der Compiler zu überprüfen, wenn Sie nicht finden können, Schlupflöcher.

und dynamic_cast tut dasselbe, wobei zusätzlich geprüft wird, ob der Zeiger in den gewünschten Typ gecastet werden kann, d. h. ob es sich um einen Zeiger dieses Typs oder einer Unterklasse handelt.

Wenn der Zeiger defekt ist, kann dynamic_cast nichts erkennen und gibt NULL zurück.

Aus diesem Grund habe ich CheckPointer nicht verwendet. Aber ich benutze diesen Scheck in der Regel überall, wo ich nicht in Gefahr bin. Immerhin, einen Fehler in einer Software zu finden, die nicht heruntergefallen ist, scheint ein wenig einfacher zu sein).

Und was ist mit non-const - theoretisch können wir eine Methode wie GetRatingByAnyFormula() { m_rating01=Formula01(); return m_rating01;} haben.

wäre recht umständlich, wenn sie nicht gleich bei der Sortierung verwendet würde, d.h. wir müssten erst die Bewertung zählen und dann die Sortierung nach ihr aufrufen. Oder Sie können, wie bereits erwähnt, Ihr eigenes SB von Grund auf neu schreiben).

  1. Die Compare-Methoden sind als öffentlich definiert, was bedeutet, dass jeder Außenseiter, egal wie sehr man versucht, es in der Spezifikation zu erklären, dort einen ungültigen Deskriptor hinschieben wird. Wenn es sich nicht um eine Bibliothek handelt, sondern nur für Sie selbst, müssen Sie das natürlich nicht.
  2. Ich weiß nicht, wie CheckPointer funktioniert, da bis zu . In jedem Fall handelt es sich aber um den Takt des Prozessors und den Speicherzugriff (es könnte sich auch leicht als virtueller Speicher herausstellen).
  3. Über Methoden mit dem Spezifizierer const. Wenn Sie eine Bibliothek schreiben, müssen Sie immer daran denken, dass das Objekt möglicherweise eine Konstante sein muss, also in den Methoden, die den Zustand des Objekts nicht ändern, wie es wünschenswert ist. Bislang habe ich mich aber nicht wirklich darum gekümmert.
  4. Wenn Sie Ihr eigenes System schreiben, ist dies wahrscheinlich die richtige Entscheidung. Das sind nur interessante Aussichten im Lohn-/Arbeitsverhältnis, die noch nicht sichtbar sind und daher auch nicht fertiggestellt werden, also nur für den eigenen Bedarf).
 
Vladimir Simakov:

Über meinen !node-Check. Es sollte durch CheckPointer(node)==POINTER_INVALID ersetzt werden, aber das ist ein Overhead, Funktionsaufruf.

Das Problem liegt nicht im Overhead, sondern in der Tatsache, dass ein defekter Zeiger die Logik des Programms verändert, d.h. anstatt das Problem zu erkennen, wird es noch tiefer begraben.

CheckPointer sollte nur für Debugging-Zwecke oder als Implementierung eines schwachen Zeigers verwendet werden.

 
Vladimir Simakov:
  1. Compare-Methoden sind als öffentlich definiert, so dass jeder Außenseiter, egal wie sehr man ihn in der Spezifikation darauf hinweist, einen ungültigen Deskriptor dorthin schieben wird (nennen wir die Dinge bei ihrem richtigen Namen). Wenn es sich nicht um eine Bibliothek handelt, sondern nur für Sie selbst, müssen Sie das natürlich nicht.
  2. Ich weiß nicht, wie CheckPointer funktioniert, da bis zu . In jedem Fall handelt es sich aber um den Takt des Prozessors und den Speicherzugriff (es könnte sich auch leicht als virtueller Speicher herausstellen).
  3. Über Methoden mit dem Spezifizierer const. Wenn Sie eine Bibliothek schreiben, müssen Sie immer daran denken, dass das Objekt eine Konstante benötigen kann, also in den Methoden, die den Zustand des Objekts nicht ändern, wie es wünschenswert ist. Bislang habe ich mich allerdings nicht wirklich darum gekümmert.
  4. Wenn Sie Ihr eigenes System schreiben, ist dies wahrscheinlich die richtige Entscheidung. Das sind halt interessante Perspektiven im Lohn/Arbeitsverhältnis, die noch nicht sichtbar sind und deshalb auch nicht gebracht werden, also nur für den eigenen Bedarf).

1. Kein Argument, aber was ich sagen wollte, ist, dass man KEINEN CheckPointer braucht (auch nicht für Underdogs), weil dynamic_cast darf KEINEN nicht-ungültigen Zeiger zurückgeben, sondern nur NULL.

2. Es ist sogar interessant, aber mir fällt auf Anhieb kein Beispiel ein, das es ermöglichen würde, einen nicht ungültigen Zeiger zu erhalten, außer das dynamische Objekt zu töten oder den Speicher direkt zu "verschmutzen", während man an ihm arbeitet.

Ich nehme an, dass es noch solche Möglichkeiten gibt, aber sie liegen wahrscheinlich alle auf der Ebene der Umgehung von Compilerprüfungen.

3,4 Einverstanden.

P.S.

Ich muss mich bei der 1. geirrt haben. Der Test sagt das Gegenteil aus. Es muss nur ein Eindruck sein.)

void OnStart()
  {
      CChartObjectRectangle *base = new CChartObjectRectangle();
      CChartObjectRectangleX *rect = new CChartObjectRectangleX();
       CChartObjectRectangle * dbase  ;
      const CChartObjectRectangleX *drect  ;
      Print("dbase= ",dbase, " NULL ? ",dbase==NULL," check? ",!dbase, " broken? ", EnumToString( CheckPointer(dbase) ));
      dbase=dynamic_cast< CChartObjectRectangle *>  (base);
      Print("dbase= ",dbase, " NULL ? ",dbase==NULL, " check? ",!dbase," broken? ", EnumToString( CheckPointer(dbase) ));
      delete base;
      Print("dbase= ",dbase, " NULL ? ",dbase==NULL," check? ",!dbase, " broken? ", EnumToString( CheckPointer(dbase) ));
      dbase=dynamic_cast< CChartObjectRectangle *>  (base);   
      Print("dbase= ",dbase, " NULL ? ",dbase==NULL," check? ",!dbase, " broken? ", EnumToString( CheckPointer(dbase) ));   
  }
 
Ist es möglich, ein statisches Array im öffentlichen Klassenteil zu deklarieren und es im Konstruktor zu initialisieren? (wie unten) (oder nur Element für Element?)
 bool Mass[5] = { false, true, false, true, true };
 
Pavel Verveyko:
Kann ein statisches Array im öffentlichen Klassenteil deklariert und im Konstruktor initialisiert werden? (wie unten) (oder nur Element-für-Element?)

Sie können ein lokales Array initialisieren und ein ArrayCopy in das entsprechende Arrayfeld durchführen:

class A{
public:
   bool Mass[5];
   A(){
       bool mass_init[5] = { false, true, false, true, true };
       ArrayCopy(Mass, mass_init);
   }
};
Grund der Beschwerde: