PLO. Fragen zur Anwendung - Seite 5

 

Irgendwie ist die Frage , ob Multi-Purposing die Verarbeitungsgeschwindigkeit des CPU-Codes beeinflusst oder nicht, völlig unbeachtet geblieben(2011.04.04 21:58).

Wenn die Frage falsch, dumm usw. erscheint. - dann schreiben Sie das.

 
Yedelkin:

Die Frage , ob sich die Mehrfachverwendung auf die Codeverarbeitungsgeschwindigkeit des Prozessors auswirkt oder nicht(2011.04.04 21:58), bleibt irgendwie völlig unbeachtet.

Wenn die Frage falsch, dumm usw. erscheint. - schreiben Sie es einfach so.

Die Frage ist völlig logisch, die Antwort lautet: Nein, das ist nicht der Fall.

2011.04.09 10:21:31     Черновик 31 (GBPUSD,H1) время c обёртками=1656
2011.04.09 10:21:29     Черновик 31 (GBPUSD,H1) время без обёртки=1766


class CA
  {
private:
   uint              func1(int count){return(func2(count));};
   uint              func2(int count){return(func3(count));};
   uint              func3(int count){return(func4(count));};
   uint              func4(int count){return(func5(count));};
   uint              func5(int count){return(func6(count));};
   uint              func6(int count){return(func7(count));};
   uint              func7(int count){return(func8(count));};
   uint              func8(int count){return(func9(count));};
   uint              func9(int count)
     {
      uint start=GetTickCount();
      double a=123456.4567879;double b=234.568;double temp;
      for(int i=0;i<count;i++)
        {
         if(i%2==0)temp=a/b;
         else temp=a*b;
        }
      return(GetTickCount()-start);
     };
public:
                     CA(void){};
                    ~CA(void){};
   uint              func(int count){return(func1(count));};

  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
          Print("время без обёртки=",  func(100000000));
   CA a; Print("время c обёртками=",a.func(100000000));
  }
//+------------------------------------------------------------------+
uint func(int count)
  {
   uint start=GetTickCount();
   double a=123456.4567879;double b=234.568;double temp;
   for(int i=0;i<count;i++)
     {
      if(i%2==0)temp=a/b;
      else temp=a*b;
     }
   return(GetTickCount()-start);
  }
//+------------------------------------------------------------------+
 

Ich hab's! Nun, Sie haben mich sehr ermutigt! Ich werde jetzt die Freude am Stempeln von verschachtelten Methoden verdoppeln :)

Urain, danke für das Beispiel! Auch wenn Sie keine Programmiererfahrung haben, ist es manchmal schwer zu erraten, wie Sie den korrekten Code überprüfen und schreiben sollen. Und hier ist alles klar und verständlich.

 

Frage. Kann sich eine Instanz einer untergeordneten Klasse selbst löschen? Mit anderen Worten: Wird ein solches Konstrukt funktionieren?

class C_A
  {
public:
                     C_A(){};
                    ~C_A(){};
   void Del(C_A *p)
     {
      if(CheckPointer(p)==POINTER_DYNAMIC)
        {
         delete p;
        }
     }
  };
class C_B : public C_A
  {
public:
                     C_B(){};
                    ~C_B(){};
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   C_A *pointer=new C_B;
   pointer.Del(pointer);
  }
Der Compiler beschwert sich nicht über dieses Konstrukt.
 
Yedelkin:

Frage. Kann sich eine Instanz einer untergeordneten Klasse selbst löschen? Mit anderen Worten: Wird diese Konstruktion funktionieren?

Der Compiler beschwert sich nicht über dieses Konstrukt.

Wenn ich es richtig verstehe, ich mag keine Zeiger (und ich benutze sie nicht oft, vor allem in MQL5), sollte das Kind wie folgt aussehen

class C_B : public C_A
{
public:
                     C_B(){};
                    ~C_B(){};

   void Del(C_B *p)
     {
      if(CheckPointer(p)==POINTER_DYNAMIC)
        {
         delete p;
        }
     }
};

Daher würde die Anwendung wie folgt aussehen

void OnStart()
{
C_B *pointer=new C_B;
pointer.Del(pointer);
}

PS

Ist es ein Fehler (oder eine Eigenschaft des Compilers), dass der Compiler dies übersehen hat?

Natürlich können wir davon ausgehen, dass der Nachkomme die von uns benötigte Klasse übergeben hat, aber die Strukturen und Funktionen der beiden Klassen können sehr unterschiedlich sein. Und was passiert dann?

C_A *pointer=new C_B;
 

Und wenn ich den ursprünglichen Code so verwende, tritt überhaupt ein Speicherleck auf, obwohl alle Compiler-Prüfungen bestanden wurden (und er hat nicht einmal mögliche Probleme erwähnt)

void OnStart()
{
C_B *pointer=new C_B;
pointer.Del(pointer);
}

Hier ist das Ergebnis (ich verstehe, dass das Zeigerobjekt wegen des Speicherlecks nicht korrekt gelöscht wird):

2011.04.09 19:21:07    Forum (EURUSD,D1)    16 bytes of leaked memory
2011.04.09 19:21:07    Forum (EURUSD,D1)    1 object of type C_B left
2011.04.09 19:21:07    Forum (EURUSD,D1)    1 undeleted objects left
 
Interesting:

Wenn ich es richtig verstehe, ich mag keine Zeiger (und ich benutze sie nicht oft, vor allem in MQL5), dann sollte der Nachkomme wie folgt aussehen

Sehen Sie. Ich habe die Methode void Del(C_A *p) mit dem Modifikator public in der übergeordneten Klasse deklariert. Die Kindklasse hat diese Methode also vollständig geerbt. Ich muss also nicht dieselbe Methode in der untergeordneten Klasse erneut deklarieren. In Bezug auf
C_A *pointer=new C_B;
Ich habe diese Idee von Tetris übernommen, und sie hat sich für mich bewährt. Natürlich wäre es nicht richtig, diese Linie direkt zu verwenden, aber sie eignet sich sehr gut für ähnliche Zwecke, wie sie in Tetris gelöst werden.
 
Yedelkin:

Die Frage , ob sich die Mehrfachnutzung auf die Codeverarbeitungsgeschwindigkeit des Prozessors auswirkt oder nicht(2011.04.04 21:58), bleibt dabei völlig unbeachtet.

Wenn die Frage falsch, dumm usw. erscheint. - schreiben Sie es einfach.

Die Antwort auf die Logik - je einfacher und logischer die Primitive sind, desto effizienter wird der Optimierer sein.

Die Hauptsache ist, dass man es nicht übertreibt :)

 

Der Skriptcode wurde geringfügig geändert:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_A
  {
public:
                     C_A(){ Print("Запущен класс С_А"); };
                    ~C_A(){Print("Закрыт класс С_А");};
   void Del(C_A *p)
     {
      if(CheckPointer(p)==POINTER_DYNAMIC)
        {
         delete p;
         Print("Удалён объект p");
        }
     }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B : public C_A
  {
public:
                     C_B(){ Print("Запущен класс С_В"); };
                    ~C_B(){Print("Закрыт класс С_В");};
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   C_A *pointer=new C_B;
   if(pointer!=NULL) Print("указатель pointer проинициализирован");
   pointer.Del(pointer);
  }

Ausgänge

EL      0       ttttttttttttt (EURUSD,M1)       15:08:27        Запущен класс С_А
MS      0       ttttttttttttt (EURUSD,M1)       15:08:27        Запущен класс С_В
DJ      0       ttttttttttttt (EURUSD,M1)       15:08:27        указатель pointer проинициализирован
IH      0       ttttttttttttt (EURUSD,M1)       15:08:27        Закрыт класс С_В
CG      0       ttttttttttttt (EURUSD,M1)       15:08:27        Закрыт класс С_А
RO      0       ttttttttttttt (EURUSD,M1)       15:08:27        Удалён объект p
 
Yedelkin:
Sehen Sie. Ich habe die Methode void Del(C_A *p) mit dem Modifikator public in der übergeordneten Klasse deklariert. Die Kindklasse hat diese Methode also vollständig geerbt. Ich muss also nicht dieselbe Methode in der untergeordneten Klasse erneut deklarieren. Was diese Idee betrifft, so habe ich sie von Tetris übernommen, und sie hat bei mir sehr gut funktioniert. Natürlich wäre es nicht richtig, diese Zeichenkette direkt zu verwenden, aber sie eignet sich sehr gut für ähnliche Zwecke, wie sie in Tetris gelöst werden.

Selbst wenn man davon ausgeht, dass void Del(C_A *p) im Vorgänger ausreicht, um alle Zeiger der Nachkommen zu löschen, sehe ich keinen Sinn in der Verwendung von

C_A *pointer=new C_B;

PS

Die einzige Stelle, an der ich mir die Notwendigkeit eines solchen Ansatzes vorstellen kann, ist die Erstellung eines Arrays verschiedener Objekte, die von derselben Klasse abstammen (oder die Übergabe eines Parameters vom Typ "Basisklasse" an eine Funktion oder Prozedur).