앗. 지원 질문 - 페이지 5

 

어쩐지 멀티래핑이 프로세서의 코드 처리 속도에 영향을 미치는지 여부 에 대한 질문은 완전히 무시되었습니다. ( 2011.04.04 21:58 )

질문이 올바르지 않거나 어리석은 경우 등 - 받아 적어.

 
Yedelkin :

어쩐지 멀티래핑이 프로세서의 코드 처리 속도에 영향을 미치는지 여부 에 대한 질문은 완전히 무시되었습니다. ( 2011.04.04 21:58 )

질문이 올바르지 않거나 어리석은 경우 등 - 받아 적어.

질문은 매우 논리적이며 대답은 아니오, 영향을 미치지 않습니다 .

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

이해했다! 글쎄, 당신은 나를 덮었습니다! 이제 두 배의 기쁨으로 중첩된 메서드에 스탬프를 찍을 것입니다. :)

Urain님 , 예를 들어 주셔서 감사합니다! 프로그래밍 경험이 있을 때까지는 이를 위한 올바른 코드를 확인하고 작성하는 것이 자신을 추측하기 어려울 때가 있습니다. 그리고 여기 모든 것이 명확하고 이해할 수 있습니다.

 

문제. 자식 클래스의 인스턴스가 자신을 삭제할 수 있습니까? 즉, 다음과 같이 작동합니다.

 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);
  }
컴파일러는 이 구성에 대해 불평하지 않습니다.
 
Yedelkin :

문제. 자식 클래스의 인스턴스가 자신을 삭제할 수 있습니까? 즉, 다음과 같이 작동합니다.

컴파일러는 이 구성에 대해 불평하지 않습니다.

모든 것을 올바르게 이해했다면 포인터가 마음에 들지 않습니다(특히 MQL5에서 자주 사용하지 않음). 그러면 아이는 다음과 같이 보일 것입니다.

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

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

따라서 아이디어에 따른 응용 프로그램은 다음과 같습니다.

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

추신

그러나 컴파일러가 이것을 놓친 것은 버그(또는 컴파일러의 설명되지 않은 기능)가 아닙니까?

물론 자손이 필수 클래스로 롤링된다고 가정할 수 있지만 두 클래스의 구조와 기능은 매우 다를 수 있습니다. 그 다음엔?

C_A *pointer= new C_B;
 

그리고 이 초기 코드를 사용하면 컴파일러의 모든 검사가 통과되었지만 일반적으로 메모리 누수가 발생합니다(그리고 그는 가능한 문제에 대해서도 암시하지 않았습니다).

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

결과는 (내가 알기로는 메모리 누수로 인해 포인터 개체가 올바르게 삭제되지 않았습니다):

 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 :

모든 것을 올바르게 이해했다면 포인터가 마음에 들지 않습니다(특히 MQL5에서 자주 사용하지 않음). 그러면 아이는 다음과 같이 보일 것입니다.

잘 봐. 부모 클래스에서 public 한정자를 사용하여 void Del(C_A *p) 메서드를 선언했습니다. 이것은 자식 클래스가 이 메서드를 완전히 상속했음을 의미합니다. 따라서 자손 클래스에서 동일한 메소드를 다시 선언할 필요가 없습니다. 에 관하여
C_A *pointer= new C_B;
그런 다음 Tetris에서 이 아이디어를 훔쳐보고 매우 유용한 것으로 판명되었습니다. 물론 이 라인을 무작정 사용하는 것은 틀리겠지만, 테트리스에서 해결한 것과 비슷한 용도로는 매우 적합하다.
 
Yedelkin :

어쩐지 멀티래핑이 프로세서의 코드 처리 속도에 영향을 미치는지 여부 에 대한 질문은 완전히 무시되었습니다. ( 2011.04.04 21:58 )

질문이 올바르지 않거나 어리석은 경우 등 - 받아 적어.

대답은 논리적입니다. 기본 요소가 더 단순하고 논리적일수록 최적화 프로그램이 더 효율적으로 작동합니다.

이 경우 가장 중요한 것은 과용하지 않는 것입니다 :)

 

스크립트 코드를 약간 수정했습니다.

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

문제

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 :
잘 봐. 부모 클래스에서 public 한정자를 사용하여 void Del(C_A *p) 메서드를 선언했습니다. 이것은 자식 클래스가 이 메서드를 완전히 상속했음을 의미합니다. 따라서 자손 클래스에서 동일한 메소드를 다시 선언할 필요가 없습니다. 이 아이디어에 관해서는 Tetris에서 스파이를 했고 그것은 나에게 매우 유용한 것으로 판명되었습니다. 물론 이 라인을 무작정 사용하는 것은 틀리겠지만, 테트리스에서 해결한 것과 비슷한 용도로는 매우 적합하다.

조상의 void Del(C_A *p) 이 모든 자식의 포인터를 삭제하기에 충분하다고 가정하더라도 사용할 이유가 없습니다.

C_A *pointer= new C_B;

추신

그러한 접근 방식의 필요성을 상상할 수 있는 유일한 장소는 동일한 클래스의 자손인 이질적인 객체의 배열을 생성하는 것입니다(옵션으로 "기본" 클래스 유형의 매개변수를 함수에 전달하거나 절차).