MQL5의 OOP에 대한 질문 - 페이지 35

 
Roman :

객체가 목적을 달성했다면 왜 메모리에 보관합니까?
메모리 누수가 발생합니까?

특히 OnDeinit에서도 삭제되지 않으면 발생합니다.
더 이상 필요하지 않은 경우 메모리에 저장할 수 없습니다. 그러나 더 자주 객체가 생성되어 한 번의 반복에서 사용되는 일이 발생합니다... 그리고 두 번째 반복에서... 등등. 그런 다음 특정 조건에서 동일한 클래스의 다른 개체가 생성되고 이미 이 클래스의 두 개 이상의 개체로 작업합니다. 각 개체는 고문의 수명 내내 필요합니다.

 
BlackTomcat :

특히 OnDeinit에서도 삭제되지 않으면 발생합니다.
더 이상 필요하지 않은 경우 메모리에 저장할 수 없습니다. 그러나 더 자주 객체가 생성되어 한 번의 반복에서 사용되는 일이 발생합니다... 그리고 두 번째 반복에서... 등등. 그런 다음 특정 조건에서 동일한 클래스의 다른 개체가 생성되고 이미 이 클래스의 두 개 이상의 개체로 작업합니다. 각 개체는 고문의 수명 내내 필요합니다.

즉, 제어된 메모리 누수가 개체를 다시 만드는 것보다 낫다고 말하고 싶습니까?
즉, 통제된 악마와 교환하여 시간을 절약하는 것입니까?
나중에 잃어버리지 않는 것은 위험합니다.

 

전문가의 템플릿에 따라 작성 https://www.mql5.com/ru/forum/85652/page24#comment_13054686

상당히 유연한 템플릿으로, "2번의 클릭"으로 다른 "빵"을 추가할 수 있으며 코드는 읽기 쉽고 논리적으로 밝혀졌습니다. 정적 메서드

이론상으로는 좋게 들립니다. 실제로는... 제 생각에는 적어도 MQL 작업의 경우 IMHO에서는 아무 것도 아닙니다.

EA 클래스는 템플릿에 따라 작성되었으며 OnTick()에서 하나의 공개 메서드가 시작되지만 EA를 초기화할 때 미결 주문이 있는지 확인하고 픽업해야 합니다. 두 가지 방법이 있습니다.

1. 아래 OnTick()에 함수를 작성합니다. 이 함수는 마법으로 열린 주문을 찾은 후 평소와 같이 EA 개체를 생성합니다. 주문을 찾지 못한 경우 기본 논리에 따라 적절하게 초기화합니다. EA 개체 거래 시간에만 생성되며 향후 TS 로직을 구현합니다.

2. 항목 1을 수행할 EA의 정적 클래스 작성


사실, 단락 1과 단락 2는 동일하지만 단락 1에서는 Expert Advisor가 초기화될 때만 의미가 있는 기능을 추가할 것이지만(처음 실행) IMHO, 이것은 코드를 복잡하게 만듭니다 - 하나의 기능 전체 실행 프로그램에 대해 한 번 호출됩니다!

정적 메서드를 만들면(2절) IMHO는 모든 것이 논리적이고 읽을 수 있으며 메서드는 초기화에만 필요하고 EA 개체를 생성해야 하는 순간만 결정합니다. 이 방법은 간단하게


제 생각에는 편리할 때 정적 메서드를 사용하는 것을 금지합니다... 음, 가볍게 말해서 옳지 않습니다!

 
Igor Makanu :

정적 메서드 는 범위에서만 함수와 다릅니다.


이 습관은 위험하다

 input int inInput = 0 ;

const bool Init = EventSetTimer ( 1 );

void OnTimer ()
{
   static int Input = inInput;
  
   Print (Input);
}


EA가 실행되는 동안 입력을 변경하면 입력이 변경되지 않습니다.

이에 따라 부담스럽다

 input long inMagic = 0 ;

void OnTick ()
{
   static ORDER Orders[]; // Список ордеров по мэджику или что-то подобное, зависящая от входных.
}
 
fxsaber :

EA가 실행되는 동안 입력을 변경하면 입력이 변경되지 않습니다.

네, 알고 있습니다. 제 TS에 따르면 EA가 실행되는 동안에는 입력 매개변수를 변경할 수 없으며 작동 시간은 TS 로직과 별도로 계산됩니다.

여기 내 질문은 순전히 이론적인 것이므로 코드를 복잡하게 만들고 싶지 않으므로 충돌 후 차량을 복원하고 어딘가에 붙일 가능성을 찾고 있습니다.

 input int EAMagicNumber = 12345 ;
class CEA
{
public :
   static bool        NeedRecovery( int magic_)            {   return ( true );    }
   bool               Recovery( int magic_, int inputparam) {   return ( true );    }
                     CEA()                               {                    }
                     CEA( int inputparam)                 {                    }
                    ~CEA()                               {                    }
};

CEA *ea;

void OnStart ()
{
   if ( CheckPointer (ea)== POINTER_INVALID )
   {
       if (CEA::NeedRecovery(EAMagicNumber))   //если нашли открытые ордера с магиком
      {
         ea = new CEA();         // создали объект
         ea.Recovery(EAMagicNumber, 11111 );   // запустили восстановление ТС
      } else ea = new CEA( 2222222 );           //обычный запуск
   }
 
Igor Makanu

이 논리를 생성자에 넣는 것이 더 논리적입니다.

 
fxsaber :

정적 메서드 는 범위에서만 함수와 다릅니다.

잘못된. 또한 클래스의 비공개 멤버 및 메서드에 액세스할 수 있습니다.
 
TheXpert :
잘못된. 또한 클래스의 비공개 멤버 및 메서드에 액세스할 수 있습니다.

여기에 용어상의 오해가 있습니다. "범위"는 누가 방법을 보는가에 관한 것이 아닙니다. 그러나 그는 무엇을 보는가?

 
fxsaber :

여기에 용어상의 오해가 있습니다.

결국 범위와 접근은 다른 개념이며 혼합하지 않는 것이 좋습니다.
 
fxsaber :

이 논리를 생성자에 넣는 것이 더 논리적입니다.

예, 이것이 더 나은 솔루션입니다! 한 가지 방법을 덜 사용하기 위해

다음과 같이 :

 input int EAMagicNumber = 12345 ;
class CEA
{
public :
   static bool        NeedRecovery( int magic_)            {   return ( true );    }   //тут проверки
                     CEA( int magic_)                     {                    }   //это обычный запуск если все ОК
                     CEA( int magic_, int recoveryparam)  {                    }   //тут аварийное восстановление
                    ~CEA()                               {                    } };

CEA *ea;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart ()
{   if ( CheckPointer (ea)== POINTER_INVALID )
   {   if (CEA::NeedRecovery(EAMagicNumber))   //если нашли откртые ордера с магиком
      {  
         ea = new CEA(EAMagicNumber, 11111 );   // запустили востановление ТС
      }
       else ea = new CEA(EAMagicNumber);       //обычный запуск
   } 
}
더엑스퍼트 :
결국 범위와 접근은 다른 개념이며 혼합하지 않는 것이 좋습니다.
그래서 마지막 실행이 비정상적으로 완료되었음을 감지하는 방법을 어디에 붙여야 하는지에 대한 질문이 있었습니다. 이제 코드 구조가 간결하고 위에 표시된 템플릿에 따라 모든 것이 명확합니다.
사유: