OOP. Başvuru soruları - sayfa 5

 

Her nasılsa, çoklu sarmanın işlemci tarafından kod işleme hızını etkileyip etkilemediği sorusu tamamen göz ardı edildi ( 2011.04.04 21:58 )

Soru yanlış görünüyorsa, aptalca vb. - yaz.

 
Yedelkin :

Her nasılsa, çoklu sarmanın işlemci tarafından kod işleme hızını etkileyip etkilemediği sorusu tamamen göz ardı edildi ( 2011.04.04 21:58 )

Soru yanlış görünüyorsa, aptalca vb. - yaz.

Soru oldukça mantıklı, cevap hayır, etkilemiyor .

 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);
  }
//+------------------------------------------------------------------+
 

Anladım! Beni korudun! Şimdi iç içe yöntemleri çifte zevkle damgalayacağım :)

Urain , örnek için teşekkürler! Programlama deneyiminiz olana kadar, bunun için doğru kodu kontrol edip yazmak için kendinizi tahmin etmek bazen zordur. Ve burada her şey açık ve anlaşılır.

 

Soru. Bir alt sınıfın örneği kendini silebilir mi? Başka bir deyişle, böyle bir şey işe yarar mı:

 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);
  }
Derleyici bu yapıdan şikayet etmez.
 
Yedelkin :

Soru. Bir alt sınıfın örneği kendini silebilir mi? Başka bir deyişle, böyle bir şey işe yarar mı:

Derleyici bu yapıdan şikayet etmez.

Her şeyi doğru anlarsam, işaretçileri sevmiyorum (ve onları özellikle MQL5'te sık kullanmıyorum), o zaman çocuk böyle görünmelidir.

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

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

Dolayısıyla fikre göre uygulama şu şekilde olacaktır.

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

not

Ancak derleyicinin bunu gözden kaçırması bir hata (veya derleyicinin açıklanmayan bir özelliği) değil mi?

Tabii ki, soyundan gelenin gerekli sınıf olarak yuvarlandığı varsayılabilir, ancak iki sınıfın yapıları ve işlevleri çok farklı olabilir. Ve sonra ne?

C_A *pointer= new C_B;
 

Ve ilk kodun bu şekilde kullanılmasıyla, derleyici tarafından yapılan tüm kontrollerin geçmesine rağmen (ve olası sorunlara ipucu bile vermemesine rağmen) genellikle bir bellek sızıntısı ortaya çıkar.

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

Sonuç (anladığım kadarıyla bir bellek sızıntısı nedeniyle işaretçi nesnesi doğru şekilde silinmedi):

 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 :

Her şeyi doğru anlarsam, işaretçileri sevmiyorum (ve onları özellikle MQL5'te sık kullanmıyorum), o zaman çocuk böyle görünmelidir.

İyi bak. Üst sınıfta genel değiştirici ile void Del(C_A *p) yöntemini bildirdim. Bu, alt sınıfın bu yöntemi tamamen devraldığı anlamına gelir. Bu nedenle aynı metodu tekrardan alt sınıfa bildirmeme gerek yok. İlişkin
C_A *pointer= new C_B;
sonra bu fikri Tetris'ten aldım ve benim için çok faydalı olduğu ortaya çıktı. Elbette bu hattı pervasızca kullanmak yanlış olur ama Tetris'te çözülen amaçlara benzer amaçlar için oldukça uygundur.
 
Yedelkin :

Her nasılsa, çoklu sarmanın işlemci tarafından kod işleme hızını etkileyip etkilemediği sorusu tamamen göz ardı edildi ( 2011.04.04 21:58 )

Soru yanlış görünüyorsa, aptalca vb. - yaz.

Cevap mantıklı - ilkeller ne kadar basit ve mantıklı olursa, optimize edici o kadar verimli çalışacaktır.

Önemli olan aşırıya kaçmamak :)

 

Komut dosyası kodunu biraz değiştirdi:

 //+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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);
  }

Sorunlar

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 :
İyi bak. Üst sınıfta genel değiştirici ile void Del(C_A *p) yöntemini bildirdim. Bu, alt sınıfın bu yöntemi tamamen devraldığı anlamına gelir. Bu nedenle aynı metodu tekrardan alt sınıf içinde bildirmeme gerek yok. Bu fikre gelince, Tetris'ten casusluk yaptım ve benim için çok faydalı olduğu ortaya çıktı. Elbette bu hattı pervasızca kullanmak yanlış olur ama Tetris'te çözülen amaçlara benzer amaçlar için oldukça uygundur.

Atadaki void Del(C_A *p) öğesinin herhangi bir çocuğun işaretçisini silmek için yeterli olacağını varsaysak bile, kullanmak için bir neden göremiyorum.

C_A *pointer= new C_B;

not

Böyle bir yaklaşıma ihtiyaç duyulduğunu hayal edebileceğim tek yer, aynı sınıfın torunları olan bir dizi farklı nesnenin yaratılmasıdır (seçenek olarak, "temel" sınıf türünde bir parametreyi bir işleve veya prosedür).