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

 
Dmitry Fedoseev :

표준 라이브러리 는 컨트롤이 폼에 생성됨을 의미합니다. 단지 그들이 전혀 작동하지 않는 것 같습니다. 적어도 예전에는 그랬습니다.

그래픽 인터페이스에 대한 일련의 기사에서 최신 버전의 Kazharsky를 시도해야 합니다. 얼마나 빨리 작동합니까? 그런 다음 다시 한 번 개발자에게 작성하여 자손을 수정하십시오.
 
Vasiliy Pushkaryov :
그래픽 인터페이스에 대한 일련의 기사에서 최신 버전의 Kazharsky를 시도해야 합니다. 얼마나 빨리 작동합니까? 그런 다음 다시 한 번 개발자에게 작성하여 자손을 수정하십시오.

모두가 같은 원을 걷습니다! ))) - 내가 MQL의 가능성을 연구하기 시작한 것은 그래픽 인터페이스 에 대한 이 일련의 기사에서였습니다.... - 경험이 실패했고 기사의 일부 예가 더 이상 컴파일되지 않고 저자가 연락합니다. , 하지만 라이브러리의 볼륨이 매우 커서 이 라이브러리를 사용할 수는 없지만

IMHO는 일주일 안에 C#을 공부합니다. 인터넷에 많은 예제가 있고 VS의 양식 디자이너는 Delphi와 동일하거나(나는 Delphi에서 이전에 작성했습니다) 여전히 SB를 사용합니다. 최소한 개발자의 지원이 있습니다.

 
Igor Makanu :

모두가 같은 원을 걷고 있습니다! ))) - 내가 MQL의 가능성을 연구하기 시작한 것은 그래픽 인터페이스에 관한 이 일련의 기사에서 였습니다.... - 경험이 실패했고 기사의 일부 예제가 더 이상 컴파일되지 않고 작성자가 연락합니다. , 하지만 라이브러리의 볼륨이 매우 커서 이 라이브러리를 사용할 수는 없지만

IMHO는 일주일 안에 C#을 공부합니다. 인터넷에 많은 예제가 있고 VS의 양식 디자이너는 Delphi와 동일하거나(나는 Delphi에서 이전에 작성했습니다) 여전히 SB를 사용합니다. 최소한 개발자의 지원이 있습니다.

그 라이브러리가 이미 마무리되고 있다는 소식을 듣게 되어 유감입니다. 1년 반 전에 해봤는데 패널 외관이 마음에 들었습니다. MT4에서도 수정해서 해봤는데(Canvas의 차이로 인해 바로 컴파일이 되지 않는 부분도 있음) 네, 작업에 포팅하기 어려워서 SB로 했습니다. 나중에 GUI 로 돌아갈 것이라고 생각했습니다.

나는 일주일에 C#을 거의 마스터 할 수 없습니다. 그러나 특히 .NET 라이브러리에 대한 기본 지원이 이미 있기 때문에 이 목표를 스스로 설정해야 합니다. 따라서 특정 작업에 사용할 수 있는 방법을 제안했습니다.

 
Vladimir Simakov :

그리고 두 번째 경우에는,

 void   AddValue (T & value )  { Tptr  = value ; mlist.Add(Tptr);       }

어떤 이유로 그것은 당신의 옵션으로 작동하지 않았습니다. 아마도 다시 엉망이 될 것입니다)) ,

그러나 결국 그것은 내가 원하는 것으로 밝혀졌습니다. 중간 포인터없이 목록에 직접 데이터를 저장하고 싶습니다. 이것이 메모리 누수 없이 작동하는 방법입니다.

 #property strict
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
template < typename T> class CDataBase
  {
private :
   CList            *mlist;
public :
   void CDataBase()           { mlist= new CList;                                    }
   void ~CDataBase( void )      { delete mlist;                                       }
   int ArraySize ( void )        { return (mlist.Total());                              }
   T operator []( int index)    { return (mlist.GetNodeAtIndex(index));                }
   void   AddValue (T value)   { mlist.Add(value);                                   }
   void   Delete( int pos)      { mlist.Delete(pos);                                  }
   string TypeName()          { return ( typename (T));                                }
  };

//+------------------------------------------------------------------+
class CData : public CObject
  {
public :
   int                x;
   double             y;
                     CData(){};
                     CData( int ival, double dval){x=ival;y=dval;}
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart ()
  {
   CDataBase<CData*>*data= new CDataBase<CData*>;
   int i;
   for (i= 0 ; i< 5 ; i++) data.AddValue( new CData(i,i* 2.0 ));
   Print ( "Тип БД : " , data.TypeName(), " б чтение данных :" );
   for (i= 0 ; i<data. ArraySize (); i++) Print (i, " : " ,data[i].x, " , " ,data[i].y);
   Print ( "Удалил № 3" );
   data.Delete( 3 );
   for (i= 0 ; i<data. ArraySize (); i++) Print (i, " : " ,data[i].x, " , " ,data[i].y);
   delete data;
  }
//+------------------------------------------------------------------+

이것은 내 아이디어의 시작일 뿐입니다

클래스 CData 필드 템플릿을 사용하여 파일에 쓰는 방법을 알아낼 때까지 구현하기 위해 템플릿의 이진 파일에 쓰고 읽고 싶습니다(텍스트 파일에도 쓸 수 있지만 중요하지 않음). 하지만 정말 싶어요! ;)

 
Igor Makanu :

클래스 CData 필드 템플릿을 사용하여 파일에 쓰는 방법을 알아낼 때까지 구현하기 위해 템플릿의 이진 파일에 쓰고 읽고 싶습니다(텍스트 파일에도 쓸 수 있지만 중요하지 않음). 하지만 정말 싶어요! ;)

 #property strict
#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
struct FILE
{
   const int handle;
  
  FILE( const string FileName, const int Flags ) : handle(:: FileOpen (FileName, Flags)) {}  
  ~FILE( void ) { if ( this .handle != INVALID_HANDLE ) :: FileClose ( this .handle); }
};

template < typename T>
class CList2 : public CList
{
public :  
   virtual CObject  *CreateElement( void ) { return ( new T); }
};

template < typename T> class CDataBase
  {
private :
   CList2<T>             *mlist;
public :
   void CDataBase()           { mlist= new CList2<T> ;                                    }
   void ~CDataBase( void )      { delete mlist;                                       }
   int ArraySize ( void )        { return (mlist.Total());                              }
   T* operator []( int index)    { return (mlist.GetNodeAtIndex(index));                }
   void   AddValue (T * value)   { mlist.Add(value);                                   }
   void   Delete( int pos)      { mlist.Delete(pos);                                  }
   string TypeName()          { return ( typename (T));                                }
   bool Save( const string FileName ) const { const FILE File(FileName, FILE_WRITE | FILE_BIN ); return ( this .mlist.Save(File.handle)); }
   bool Load( const string FileName ) { const FILE File(FileName, FILE_READ | FILE_BIN ); return ( this .mlist.Load(File.handle)); }

  };

//+------------------------------------------------------------------+
class CData : public CObject
  {
public :
   int                x;
   double             y;
                     CData(){};
                     CData( int ival, double dval){x=ival;y=dval;}
   virtual bool       Save( const int file_handle ) { return (:: FileWriteInteger (file_handle, this .x) && :: FileWriteDouble (file_handle, this .y)); }
   virtual bool       Load( const int file_handle )
   {
     :: ResetLastError ();
     
     this .x = :: FileReadInteger (file_handle);
     this .y = :: FileReadDouble (file_handle);
     
     return (!:: GetLastError ());
   }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart ()
  {
   CDataBase< CData >*data= new CDataBase<CData>;
   int i;
   for (i= 0 ; i< 5 ; i++) data.AddValue( new CData(i,i* 2.0 ));
   Print ( "Тип БД : " , data.TypeName(), " б чтение данных :" );
   for (i= 0 ; i<data. ArraySize (); i++) Print (i, " : " ,data[i].x, " , " ,data[i].y);
   
   data.Save( "Data.bin" );
   delete data;

   CDataBase<CData> data2;   
   data2.Load( "Data.bin" );
   Print ( "Тип БД : " , data2 .TypeName(), " б чтение данных :" );
   for (i= 0 ; i< data2 . ArraySize (); i++) Print (i, " : " , data2 [i].x, " , " , data2 [i].y);
  }
//+------------------------------------------------------------------+

나는 CList 및 CObject 로 작업한 적이 없지만 소스가 간단하기 때문에(그런데 const 수식어가 없는 어떤 이유로 가상 Save 메서드가 있음) 바로 작동했습니다.


추신: 이렇게 쓰는 것이 더 쉽습니다.

 template < typename T> class CDataBase
  {
private :
   CList2<T>            mlist; // Объект, не указатель

그러면 생성자/소멸자가 필요하지 않습니다. new/delete는 여전히 정말 유용한 곳에서 사용하는 것이 논리적입니다. 그렇지 않으면 위의 FILE과 동일하게 수행할 수 있습니다.

 
fxsaber :

CList와 CObject로 작업한 적은 없지만 소스가 간단해서 바로 해결되었습니다.

영형! 너무 빨리 응답을 받았습니다! - 감사합니다! - 밤에 할 일.

CList 및 CObject의 소스도 읽었습니다. 문제는 없지만 테스트를 수행해야 합니다.

추신: 여기, 일반적으로 내가 얻고자 하는 것... 글쎄, 그것은 보편적인 목록처럼 보입니다:

1. 생성 즉시 구조 클래스를 추가할 수 있는 곳(구현 - 내 예제 data.AddValue(new CData(i,i*2.0)) - 확인 확인)

2. 파일에 쓰고 "DB" 파일에서 읽을 수 있는 곳(템플릿 생성자가 이것을 보는 동안 쓰기 시작했습니다.

 1 . void CDataBase()           { mlist= new CList; m_file_handle= INVALID_HANDLE ;         }
2 . void CDataBase( int BaseID) { mlist= new CList;m_id=BaseID;m_file_handle=fileopen();  }

1번과 2번 파일에 쓰기/읽기 없이 작업합니다. 디스크에서 CDataBase를 생성할 때 데이터베이스를 읽고 소멸자를 호출할 때 디스크에 쓰기

....

추신:

글쎄, 왜이 모든 것이? - 나는 표준 체계에 따라 고문을 작성합니다 - 마법에 의한 주문을 검색하여 주문에 대한 모든 조작, TS가 "101 표시기"에 따르지 않지만 더 복잡한 경우 일반적으로 2개의 마법으로 충분합니다. 그러나 다음과 같은 경우 80개의 보류 주문을 추적하는 TS(10개의 주문 그리드, 그리드가 다시 열리고 ... 솔직히 말해서 터무니없는 TS이지만 이미 두 번째로 발생했습니다), 다양한 트릭이 시작됩니다. - 80개에 대해 80개의 주문을 실행합니다. 생성 된 마법))) - 나갔지만이 모든 것이 마음에 들지 않습니다.

그래서 결국 주문에 대한 데이터를 수 있는 작은 데이터베이스를 만들고 싶습니다. 어드바이저를 시작하거나 끌 때

이 같은 )))


fxsaber :

추신: 이렇게 쓰는 것이 더 쉽습니다.

그러면 생성자/소멸자가 필요하지 않습니다. new/delete는 여전히 정말 유용한 곳에서 사용하는 것이 논리적입니다. 그렇지 않으면 위의 FILE과 동일하게 수행할 수 있습니다.

감사합니다. 하지만 여전히 그것에 대해 생각해야 합니다 ... 또는 오히려 미래에 생각하지 않도록 하고 싶습니다))) - OnInit()에서 데이터베이스를 생성하고 파일을 읽습니다. DeInit()에서 그들은 데이터베이스를 죽이고 파일을 썼고 DeInit()에서 삭제를 놓친 경우 터미널 자체가 이것을 로그에 기록합니다... 제 생각에는 이렇게 하면 데이터베이스 작업 시 오류가 제거됩니다. .. 일반적으로 해보면 얼마나 편리한지 알겠지만

 
fxsaber :
 virtual bool       Load( const int file_handle )
   {
     :: ResetLastError ();
     

그것이 어렵지 않다면 https://www.mql5.com/en/docs/basis/operations/other 에서 "::"를 사용하는 이유는 무엇입니까?

 
Igor Makanu :

어렵지 않다면 여기서 "::"를 사용하는 이유는 무엇입니까?

그렇지 않으면 부모 클래스에 같은 이름의 메서드가 없는지 확인해야 합니다. 그리고 그렇지 않더라도 누군가 추가하면 코드는 계속 작동합니다.

같은 이유로 나는 항상 이것을 명확성과 가독성을 위해 사용합니다.


ZY 그러나 일부 드문 상황에서 :: 그리고 이것은 유연성을 박탈합니다. 클래스 내부에 메소드 본문을 작성하는 것이 더 나은 경우와 외부에 작성하는 경우와 유사한 미묘함이 있습니다. 나는이 모든 것에 직면했다는 것을 기억하지만 나는 예를 제시하지 않을 것입니다.

 
fxsaber :

그렇지 않으면 부모 클래스에 같은 이름의 메서드가 없는지 확인해야 합니다. 그리고 그렇지 않더라도 누군가 추가하면 코드는 계속 작동합니다.

같은 이유로 나는 항상 이것을 명확성과 가독성을 위해 사용합니다.

예, 정말 실용적이고 버그의 출현을 제거합니다. 서비스에 사용할 것입니다.

고맙습니다!

 
Igor Makanu :

4. m_fsave 파일에 쓰기 위한 플래그 가 활성화되어 있으면 AddValue() 메서드를 호출할 때마다 파일에 씁니다.

CList 레코드 형식을 살펴보십시오. 당신은 그를 무시하고 있습니다.