Gespräche über die PLO in der Lounge - Seite 5

 
Alexey Volchanskiy:

Ich habe gelesen, dass jeder unterschiedliche Interessen hat... Ich bin gerade dabei, eine Klasse für die virtuelle Rasterdarstellung und -steuerung neu zu entwerfen, ich brauche sie.

Und ich kämpfe schon seit 2 Tagen mit dem Kopierkonstruktor und dem Zuweisungsoperator. Es handelt sich um eine komplizierte Klasse mit Datenelementen in Form von Zeigern...

 
Dennis Kirichenko:

Ich kämpfe schon seit 2 Tagen mit dem Kopierkonstruktor und dem Zuweisungsoperator. Es gibt eine komplexe Klasse mit Datenelementen in Form von Zeigern...

Ich scheine sehr primitive Dinge zu schreiben...

 
Dennis Kirichenko:

Sie können einen Zeiger auf eine Funktion verwenden.

Wird das auch mit einer virtuellen Funktion funktionieren?

Ich habe Funktionszeiger intern immer abgelehnt, und ich weiß nicht mehr, warum bei der Arbeit in "reinem C" Funktionszeiger verwendet wurden. Aber als ich zu C++ wechselte, musste ich sie aus irgendeinem Grund aufgeben. Und seitdem habe ich sie nicht mehr benutzt. Ein Zeiger - er muss auf ein Objekt verweisen.

Aber ich werde nicht sagen, dass ich "absolut richtig" liege. Ich stimme zu, dass ich eine Menge Erfahrung der alten Schule in mir habe.

 
fxsaber:

Ich scheine sehr primitive Dinge zu schreiben...

Seien Sie nicht bescheiden.

Ich glaube nicht, dass Ihnen jemand das Wasser reichen kann, wenn es darum geht, Definitionen virtuos zu verwenden.

 
George Merts:


...Bei mir sieht diese Funktion wie folgt aus:

int CFactoryBalanceResultSeries::Compare(const CObject *poNode,const int iMode) const
{
   CFactoryBalanceResultSeries* pfdsAnother = CONVERT_OBJECT_WITH_CHECK(poNode,CFactoryBalanceResultSeries,MOT_FACTORYBALANCERES_SERIES);
   
   switch(iMode)
      {
      case FSM_BY_PART_OF_MAX_DD_A:    return(_CompareByPartOfMaxDDWith(pfdsAnother,true));
      case FSM_BY_PART_OF_MAX_DD_D:    return(_CompareByPartOfMaxDDWith(pfdsAnother,false));

      case FSM_BY_PART_OF_MAX_SLQUEUE_A: return(_CompareByPartOfMaxSLQueueWith(pfdsAnother,true));
      case FSM_BY_PART_OF_MAX_SLQUEUE_D: return(_CompareByPartOfMaxSLQueueWith(pfdsAnother,false));

      case FSM_BY_LAST_PRCDATA_A:      return(_CompareByLastPrcdataWith(pfdsAnother,true));
      case FSM_BY_LAST_PRCDATA_D:      return(_CompareByLastPrcdataWith(pfdsAnother,false));
      case FSM_BY_LAST_MNYDATA_A:      return(_CompareByLastMnydataWith(pfdsAnother,true));
      case FSM_BY_LAST_MNYDATA_D:      return(_CompareByLastMnydataWith(pfdsAnother,false));
      case FSM_BY_LAST_MNYLOTDATA_A:   return(_CompareByLastMnylotdataWith(pfdsAnother,true));
      case FSM_BY_LAST_MNYLOTDATA_D:   return(_CompareByLastMnylotdataWith(pfdsAnother,false));
      
      case FSM_BY_PRCYEARRECOVERY_A:   return(_CompareByYearPrcrecoveryWith(pfdsAnother,true));
      case FSM_BY_PRCYEARRECOVERY_D:   return(_CompareByYearPrcrecoveryWith(pfdsAnother,false));
      case FSM_BY_MNYYEARRECOVERY_A:   return(_CompareByMnyYearRecoveryWith(pfdsAnother,true));
      case FSM_BY_MNYYEARRECOVERY_D:   return(_CompareByMnyYearRecoveryWith(pfdsAnother,false));
      case FSM_BY_MNYLOTYEARRECOVERY_A:return(_CompareByMnylotYearRecoveryWith(pfdsAnother,true));
      case FSM_BY_MNYLOTYEARRECOVERY_D:return(_CompareByMnylotYearRecoveryWith(pfdsAnother,false));
      
      case FSM_BY_PRCVAR_A:            return(_CompareByPrcVarWith(pfdsAnother,true));
      case FSM_BY_PRCVAR_D:            return(_CompareByPrcVarWith(pfdsAnother,false));
      case FSM_BY_MNYVAR_A:            return(_CompareByMnyVarWith(pfdsAnother,true));
      case FSM_BY_MNYVAR_D:            return(_CompareByMnyVarWith(pfdsAnother,false));
      case FSM_BY_MNYLOTVAR_A:         return(_CompareByMnylotVarWith(pfdsAnother,true));
      case FSM_BY_MNYLOTVAR_D:         return(_CompareByMnylotVarWith(pfdsAnother,false));
      
      case FSM_BY_PRC_GRAILRATIO_A:    return(_CompareByPrcGrailratioWith(pfdsAnother,true));
      case FSM_BY_PRC_GRAILRATIO_D:    return(_CompareByPrcGrailratioWith(pfdsAnother,false));

      case FSM_BY_MAGIC_A:             return(_CompareByMagicWith(pfdsAnother,true));
      case FSM_BY_MAIGC_D:             return(_CompareByMagicWith(pfdsAnother,false));
      default:
         break;
      };
         
   return(NULL);
};

George, Sie können hier nicht sehen, ob _CompareByPrcVarWith() eine Klassenmethode oder eine gewöhnliche Funktion ist, zum Beispiel. In C++ gibt es Zeiger auf Klassenmethoden. Sie haben dort ihre eigenen Besonderheiten. Um ehrlich zu sein, habe ich noch nicht versucht, solche Zeiger in MQL5 zu verwenden.

Aber ich denke, dass Sie noch Reserven für die Verbesserung der Codestruktur haben.

Denn was ist eine Funktion?

FUNKTION(lat.functio, "Ausführung, Leistung; Aufgabe") ist eine Beziehung zwischen Elementen, bei der eine Veränderung des einen eine Veränderung des anderen nach sich zieht.

Es ist eine Funktion, die etwas tut. Dieselben Aktionen sollten im Hauptteil einer Funktion zusammengefasst werden.

In Ihrem Beispiel ist es offensichtlich, dass die Funktionen

_CompareByPartOfMaxDDWith(),

_CompareByPartOfMaxSLQueueWith(),

_CompareByLastPrcdataWith(),

_CompareByLastMnydataWith(), usw.

führen Sie einen VERGLEICH durch und geben Sie das Ergebnis dieses Vergleichs an. Sie unterscheiden sich durch ihre Namen. Ich denke, das ist keine gute Praxis. Sie sollten sich durch Parameter unterscheiden.

Also. Ich denke, wir sollten entweder alle Funktionen in einer einzigen zusammenfassen oder sie zu virtuellen Methoden oder Vorlagenmethoden machen. Natürlich müssen die Klassen der "Eltern-Sohn"-Hierarchie folgen.

Im Allgemeinen ist es sehr einfach, komplexen Code zu schreiben und sehr schwierig, einfachen Code zu schreiben.

 
Dennis Kirichenko:

George, Sie können hier nicht erkennen, ob _CompareByPrcVarWith() eine Klassenmethode oder eine gewöhnliche Funktion ist. In C++ gibt es Zeiger auf Klassenmethoden. Sie haben dort ihre eigenen Besonderheiten. Ehrlich gesagt, habe ich nicht versucht, solche Zeiger in MQL5 zu verwenden.

Diese (und alle anderen, die mit einem Unterstrich beginnen) ist eine geschützte Funktion der Klasse.

Sie beschäftigen sich mit ARRANGEMENT und geben das Ergebnis dieses Vergleichs bekannt. Sie unterscheiden sich durch ihre Namen. Ich denke, das ist keine gute Praxis. Sie sollten sich besser in den Parametern unterscheiden.

Also. Ich denke, Sie sollten entweder alle Funktionen in einer einzigen zusammenfassen oder sie als virtuelle Methoden oder Vorlagenmethoden einrichten. Natürlich müssen die Klassen der "Eltern-Sohn"-Hierarchie folgen.

Nun, sie sind alle zu einem einzigen verschmolzen!

Es gibt nur eine Funktion - Compare(), die aber einen Vergleich mit einem übergebenen Schlüssel durchführen muss. Dementsprechend wählen wir eine der spezifischen Schutzfunktionen. Deshalb sind sie geschützt (protected), so dass der Benutzer keinen Zugriff auf sie hat - sie werden nur von Compare() aufgerufen, was durch Unterstreichung angezeigt wird.

Dies ist auch eine der Regeln für die Gestaltung des Codes - eine Funktion, die mit einem Unterstrich beginnt, ist nicht dafür gedacht, von Benutzern aufgerufen zu werden, sie dient nur bestimmten klasseninternen Aufgaben. Der Zugang zu ihr ist eingeschränkt.

 
Dennis Kirichenko:

Ich kämpfe schon seit 2 Tagen mit dem Kopierkonstruktor und dem Zuweisungsoperator. Es gibt eine komplexe Klasse mit Datenelementen in Form von Zeigern...


Denis, ich wollte sagen, dass jeder einen anderen Ansatz hat. Als ich gestern den Thread eröffnete, war ich gespannt, ob die Nörgler von gestern auftauchen würden, à la "a-a-a-a-a OOP ist sehr kompliziert, SB ist eine schreckliche Blackbox". Sie sind nicht aufgetaucht, was ja auch zu erwarten war.

Aber es haben sich Menschen herauskristallisiert, und jeder hat einen anderen Ansatz. Interessant ist es auch im Hinblick auf die gemeinsamen Projekte, von denen Renat so viel spricht.

ZS: Die gemeinsame Nutzung von Projekten funktioniert immer noch nicht, ich habe es kürzlich ausprobiert.

 
George Merts:

Diese (und alle, die mit einem Unterstrich beginnen) sind Schutzfunktionen der Klasse.

Nun, sie sind zu einem einzigen verschmolzen!

Es gibt nur eine Funktion - Compare(), aber sie muss einen Vergleich mit einem übergebenen Schlüssel durchführen. Dementsprechend wird eine der beanstandeten Funktionen ausgewählt. Deshalb sind sie geschützt (protected), so dass der Benutzer keinen Zugriff auf sie hat - sie werden nur von Compare() aufgerufen, was durch Unterstreichung angezeigt wird.

Dies ist auch eine der Regeln für die Gestaltung des Codes - eine Funktion, die mit einem Unterstrich beginnt, ist nicht dafür gedacht, von Benutzern aufgerufen zu werden, sie dient nur bestimmten klasseninternen Aufgaben. Der Zugang zu ihr ist eingeschränkt.


Wie werden sie zusammengeführt, wenn Sie viele _CompareXXX()-Methoden haben? Und wenn ich es richtig verstanden habe, sollte es 1 geben.

Frage: Wird zum Beispiel die Methode_CompareByPartOfMaxDDWith() irgendwo anders als in CFactoryBalanceResultSeries::Compare() aufgerufen?

 
Dennis Kirichenko:

Wie fügen Sie zusammen, wenn Sie viele _CompareXXX()-Methoden haben? Und wenn ich es richtig verstanden habe, sollte es 1 geben.

Frage: Wird zum Beispiel die Methode_CompareByPartOfMaxDDWith() irgendwo anders als in CFactoryBalanceResultSeries::Compare() aufgerufen?

Wenn die Methode _CompareXXX() allein ist, unterscheidet sie sich nicht von der ursprünglichen virtuellen Funktion Compare().

Der Punkt ist, dass die _CompareBy...()-Methoden nur von der Hauptfunktion Compare() aufgerufen werden. Und der Unterstrich am Anfang warnt davor.

Die allgemeine Methode Compare() akzeptiert Zeiger auf zwei Objekte und den Schlüssel, der den Vergleich angibt. Bei dieser allgemeinen Methode wird der Schlüssel analysiert, und danach wird die spezielle Methode aufgerufen, die für den Vergleich nur eines Schlüssels bestimmt ist. Außerdem berechnet jede dieser Methoden den Wert der Schlüssel von zwei übergebenen Objekten, und je nachdem, ob der Schlüssel int, double, bool oder string ist, wird die (ebenfalls geschützte) Methode des Vergleichs des konkreten Typs aufgerufen.

Alle Methoden _CompareBy...() - könnten wir in eine Funktion schreiben. Aber dann würde sich meiner Meinung nach die Lesbarkeit des Codes verschlechtern.

 
George Merts:

Wenn es nur eine _CompareXXX()-Methode gibt, unterscheidet sie sich nicht von der ursprünglichen virtuellen Funktion Compare().

Der Punkt ist, dass die _CompareBy...()-Methoden nur von der Hauptfunktion Compare() aufgerufen werden. Und der Unterstrich am Anfang warnt davor.

Die allgemeine Methode Compare() akzeptiert Zeiger auf zwei Objekte und den Schlüssel, der den Vergleich angibt. Bei dieser allgemeinen Methode wird der Schlüssel analysiert, und danach wird die spezielle Methode aufgerufen, die für den Vergleich nur eines Schlüssels ausgelegt ist. Und jede dieser Methoden berechnet den Wert der Schlüssel von zwei übergebenen Objekten und je nachdem, ob der Schlüssel int, double, bool oder string ist - es wird die Methode (auch geschützt) des Vergleichs des konkreten Typs genannt.

Alle _CompareBy...()-Methoden könnten in einer einzigen Funktion geschrieben werden. Aber dann würde sich meiner Meinung nach die Lesbarkeit des Codes verschlechtern.


Ich verstehe, was Sie meinen. Ich denke, das ist Geschmackssache. Aber ich würde alles mit einer Methode machen. Insbesondere, wenn geschützte und private Methoden nirgendwo anders als beiCompare() aufgerufen werden.