کلاس در زبان MQL5

کلاس در زبان MQL5 – بخش 1

مبانی زبان MQL5 – بخش 6
مبانی زبان MQL5 – بخش 6

در دو مقاله‌ی پیشین یعنی چهارمین و پنجمین مقاله آموزش زبان mql از سری مقالات مرتبط با برنامه نویسی در بازار‌ها‌ی مالی به شرح و بررسی «ساختار در زبان MQL5» پرداختیم. در ششمین مقاله‌ی این سری نیز به «کلاس در زبان MQL5» می‌پردازیم.

در صورت برقراری شرایط معاملات الگوریتمی در بازار هدف برای اعمال هر یک از این مفاهیم در استراتژی‌های معاملاتی می‌توانید از سفارش کد پایتون، سفارش کد mql و … برای کد کردن و بهینه‌یابی استراتژی‌های معاملاتی خود استفاده کنید. و در عین حال سوای امکان سفارش اکسپرت می‌توانید از سفارش اندیکاتور برای دریافت یک نمایش گرافیکی از محاسبات استراتژی خود بهره ببرید.

– – –

انواع داده های پیچیده (Complex data types)

کلاس در زبان MQL5 - بخش 1
کلاس در زبان MQL5 – بخش 1

در دو مقاله‌ی پیشین یعنی سومین و چهارمین مقاله آموزش زبان mql از سری مقالات مرتبط با برنامه نویسی در بازار‌ها‌ی مالی به شرح و بررسی «ساختار در زبان MQL5» پرداختیم. در پنجمین مقاله‌ی این سری نیز به بررسی «کلاس در زبان MQL5» می‌پردازیم.

کلاس‌ها (Classes) #

در برنامه نویسی شی گرا( Object-oriented programming)، یک کلاس blueprint یا طرحی کلی برای ایجاد اشیا (یک ساختار داده خاص)، ارائه مقادیر اولیه برای state ها یا حالت‌ها (متغیرها یا attribute ها اعضا)، و اجرای رفتار (functionها یا methodهای اعضا) است.

  • کلمه کلیدی class در تعریف(declaration) کلاس‌ها به کار برده می‌شود.

 

ساختارها و کلاس‌ها در زبان MQL5

کلاس‌ها با ساختارها در موارد زیر متفاوت هستند:

  • اعضای داده کلاس دارای نوع دسترسی پیش‌فرض private هستند(specifier private)، مگر اینکه خلاف آن مشخص شده باشد.
  • اعضای داده ساختار دارای نوع دسترسی پیش‌فرض public هستند(specifier public)، مگر اینکه خلاف آن مشخص شده باشد.
  • اشیاء کلاس همیشه جدولی از توابع مجازی(virtual functions) دارند، حتی اگر هیچ تابع مجازی در کلاس وجود نداشته باشد. ساختارها نمی‌توانند توابع مجازی داشته باشند.
  • عملگر new را می‌توان برای اشیاء کلاس اعمال کرد. این عملگر را نمی‌توان برای ساختارها اعمال کرد.
  • کلاس ها را فقط از کلاس ها می‌توان به ارث برد.
  • ساختار ها را فقط از ساختار ها می‌توان به ارث برد.
کلاس و ساختار در زبان MQL5 - بخش 1
کلاس و ساختار در زبان MQL5 – بخش 1

 

کلاس و ساختار در زبان MQL5 - بخش 2
کلاس و ساختار در زبان MQL5 – بخش 2

Constructors and Destructors

سازنده یک تابع ویژه است که به طور خودکار هنگام ایجاد یک شی از یک ساختار یا یک کلاس فراخوانی می‌شود و معمولاً برای مقداردهی اولیه(initialization) اعضای کلاس استفاده می‌شود.

علاوه بر این، ما فقط در مورد کلاس‌ها صحبت خواهیم کرد، در حالی که همین امر در مورد ساختارها نیز صدق می‌کند، مگر اینکه خلاف آن مشخص شده باشد.Default constructor-Parametric constructor

Default constructor-Parametric constructor

 

constructor و initializing sequence

  • کلاس‌ها و ساختارها می‌توانند سازنده(explicit constructor) و تخریب‌کننده(explicit destructor) صریح داشته باشند.
  • اگر constructor شما به صراحت تعریف شده باشد، مقداردهی اولیه یک ساختار یا متغیر کلاس با استفاده از دنباله مقدار‌دهی اولیه(initializing sequence) غیرممکن است.
struct trade_settings
  {
   double take;         // values of the profit fixing price
   double stop;         // value of the protective stop price
   uchar  slippage;     // value of the acceptable slippage
   //--- Constructor
          trade_settings() { take=0.0; stop=0.0; slippage=5; }
   //--- Destructor
         ~trade_settings() { Print("This is the end"); } 
  };
//--- Compiler will generate an error message that initialization is impossible
trade_settings my_set={0.0,0.0,5};

در این مثال برای رفع اررور یا می‌بایست explicit constructor حذف گردد و یا initializing sequence.

  • توجه به این نکته الزامی‌ست که تفاوتی ندارد که explicit constructor از نوع Default constructor باشد و یا Parametric constructor.

  • نام سازنده باید با نام کلاس مطابقت داشته باشد.
  • سازنده هیچ نوع مقدار خروجی ندارد. (شما می‌توانید نوع void را مشخص کنید).
  • اعضای کلاس تعریف شده – رشته‌ها، آرایه‌های پویا(dynamic arrays) و اشیایی که نیاز به مقداردهی اولیه دارند – در هر صورت، صرف نظر از اینکه سازنده وجود داشته باشد، مقداردهی اولیه خواهند شد.
  • Parametric constructor : هر کلاس می‌تواند سازنده‌های متعددی داشته باشد که بر اساس تعداد پارامترها و لیست اولیه متفاوت است. سازنده‌ای که نیاز به تعیین پارامتر دارد، سازنده پارامتری(Parametric constructor) نامیده می‌شود.
  • Default constructor : سازنده بدون پارامتر، سازنده پیش‌فرض(Default constructor) نامیده می‌شود. اگر هیچ سازنده‌ای در یک کلاس تعریف نشده باشد، کامپایلر یک Default constructor در طول کامپایل ایجاد می‌کند.
//+------------------------------------------------------------------+
//| A class for working with a date                                  |
//+------------------------------------------------------------------+
class MyDateClass
  {
private:
   int               m_year;          // Year
   int               m_month;         // Month
   int               m_day;           // Day of the month
   int               m_hour;          // Hour in a day
   int               m_minute;        // Minutes
   int               m_second;        // Seconds
public:
   //--- Default constructor
                     MyDateClass(void);
   //--- Parametric constructor
                     MyDateClass(int h,int m,int s);
  };

یک سازنده(Constructor) را می‌توان در توضیحات کلاس تعریف کرد و سپس بدنه آن را تعریف کرد. به عنوان مثال، دو سازنده MyDateClass را می‌توان به صورت زیر تعریف کرد. :

//+------------------------------------------------------------------+
//| Default constructor                                              |
//+------------------------------------------------------------------+
MyDateClass::MyDateClass(void)
  {
//---
   MqlDateTime mdt;
   datetime t=TimeCurrent(mdt);
   m_year=mdt.year;
   m_month=mdt.mon;
   m_day=mdt.day;
   m_hour=mdt.hour;
   m_minute=mdt.min;
   m_second=mdt.sec;
   Print(__FUNCTION__);
  }
//+------------------------------------------------------------------+
//| Parametric constructor                                           |
//+------------------------------------------------------------------+
MyDateClass::MyDateClass(int h,int m,int s)
  {
   MqlDateTime mdt;
   datetime t=TimeCurrent(mdt);
   m_year=mdt.year;
   m_month=mdt.mon;
   m_day=mdt.day;
   m_hour=h;
   m_minute=m;
   m_second=s;
   Print(__FUNCTION__);
  }

در مثال بالا در Default constructor، تمام اعضای کلاس با استفاده از تابع ()TimeCurrent پر می‌شوند. در Parametric constructor فقط مقادیر ساعت پر می‌شود. سایر اعضای کلاس (m_year، m_month و m_day) به طور خودکار با تاریخ فعلی مقداردهی اولیه می‌شوند.

Default constructor هنگام مقداردهی اولیه آرایه‌ای از اشیاء کلاس خود، هدف خاصی دارد. constructor ای که پارامترهای آن دارای مقادیر پیش‌فرض هستند، Default constructor نیست.

.Constructor with a parameter that has a default value is not a Default constructor

به عنوان مثال:

//+------------------------------------------------------------------+
//| A class with a default constructor                               |
//+------------------------------------------------------------------+
class CFoo
  {
   datetime          m_call_time;     // Time of the last object call
public:
   //--- Constructor with a parameter that has a default value is not a default constructor
                     CFoo(const datetime t=0){m_call_time=t;};
   //--- Copy constructor
                     CFoo(const CFoo &foo){m_call_time=foo.m_call_time;};
 
   string ToString(){return(TimeToString(m_call_time,TIME_DATE|TIME_SECONDS));};
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
// CFoo foo; // This variant cannot be used - a default constructor is not set
//--- Possible options to create the CFoo object
   CFoo foo1(TimeCurrent());     // An explicit call of a parametric constructor
   CFoo foo2();                  // An explicit call of a parametric constructor with a default parameter
   CFoo foo3=D'2009.09.09';      // An implicit call of a parametric constructor
   CFoo foo40(foo1);             // An explicit call of a copy constructor
   CFoo foo41=foo1;              // An implicit call of a copy constructor
   CFoo foo5;                    // An explicit call of a default constructor (if there is no default constructor,
                                 // then a parametric constructor with a default value is called)
//--- Possible options to receive CFoo pointers
   CFoo *pfoo6=new CFoo();       // Dynamic creation of an object and receiving of a pointer to it
   CFoo *pfoo7=new CFoo(TimeCurrent());// Another option of dynamic object creation
   CFoo *pfoo8=GetPointer(foo1); // Now pfoo8 points to object foo1
   CFoo *pfoo9=pfoo7;            // pfoo9 and pfoo7 point to one and the same object
   // CFoo foo_array[3];         // This option cannot be used - a default constructor is not specified
//--- Show the value of m_call_time
   Print("foo1.m_call_time=",foo1.ToString());
   Print("foo2.m_call_time=",foo2.ToString());
   Print("foo3.m_call_time=",foo3.ToString());
   Print("foo4.m_call_time=",foo4.ToString());
   Print("foo5.m_call_time=",foo5.ToString());
   Print("pfoo6.m_call_time=",pfoo6.ToString());
   Print("pfoo7.m_call_time=",pfoo7.ToString());
   Print("pfoo8.m_call_time=",pfoo8.ToString());
   Print("pfoo9.m_call_time=",pfoo9.ToString());
//--- Delete dynamically created arrays
   delete pfoo6;
   delete pfoo7;
   //delete pfoo8;  // You do not need to delete pfoo8 explicitly, since it points to the automatically created object foo1
   //delete pfoo9;  // You do not need to delete pfoo9 explicitly. since it points to the same object as pfoo7
  }

اگر این رشته‌ها را از کامنت خارج کنید

//CFoo foo_array[3];     // This variant cannot be used - a default constructor is not set
//

یا

//CFoo foo_dyn_array[];  // This variant cannot be used - a default constructor is not set
//

سپس کامپایلر برای آنها خطای “default constructor is not defined” را برمی‌گرداند.

  • اگر یک کلاس دارای سازنده تعریف شده توسط کاربر(user-defined constructor) باشد، default constructor توسط کامپایلر تولید نمی‌شود. توجه به این نکته الزامی‌ست که تفاوتی ندارد که user-defined constructor از جنس Default constructor و یا Parametric constructor باشد.، به هر روی در صورت تعریف constructor توسط کاربر، default constructor توسط کامپایلر تولید نمی‌شود.؛ این بدان معناست که اگر parametric constructor در یک کلاس تعریف شود اما default constructor تعریف نشده باشد، نمی‌توانید آرایه‌های اشیاء این کلاس را تعریف کنید. کامپایلر یک خطا برای این اسکریپت برمی‌گرداند. : 

اگر parametric constructor در یک کلاس تعریف شود اما default constructor تعریف نشده باشد، نمی‌توانید آرایه‌های اشیاء این کلاس را تعریف کنید.

//+------------------------------------------------------------------+
//| A class without a default constructor                            |
//+------------------------------------------------------------------+
class CFoo
  {
   string            m_name;
public:
                     CFoo(string name) { m_name=name;}
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- Get the "default constructor is not defined" error during compilation
   CFoo badFoo[5];
  }

در کد بالا نیز کامپایلر خطای “Default constructor is not defined” را برمی‌گرداند. می‌توان برای جلوگیری از این اررور کد را به شکل زیر اصلاح کرد.

//+------------------------------------------------------------------+
//| A class without a default constructor                            |
//+------------------------------------------------------------------+
class CFoo
    {
     string            m_name;
public:
     //--- Default constructor
                     CFoo(void) {};
     //--- Parametric constructor
                     CFoo(string name) { m_name = name;}
    };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
    {
//---
     CFoo badFoo[5];
    }

در این مثال، کلاس CFoo دارای یک parametric constructor تعریف شده است – در چنین مواردی، کامپایلر یک default constructor را به طور خودکار در طول کامپایل ایجاد نمی‌کند. در همان زمان که آرایه‌ای از اشیاء را تعریف می‌کنید، فرض بر این است که همه اشیا باید به طور خودکار ایجاد و مقداردهی اولیه شوند.

در هنگام راه‌اندازی خودکار یک شی، لازم است یک default constructor فراخوانی شود، اما از آنجایی که constructor پیش‌فرض به صراحت(explicitly) تعریف نشده و به دلیلی که دکرش رفت به‌ طور خودکار نیز توسط کامپایلر تولید نمی‌شود، ایجاد چنین شی‌ای غیرممکن است. به همین دلیل کامپایلر در مرحله کامپایل خطا ایجاد می‌کند.

  • نکته ی دیگر این که منطقا تا قبل از ساخت instance از constructor مطلوب باید بدنه‌ای برای تابع این constructor حال خواه در داخل و خواه خارج کلاس تعریف شود. :
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
class MyDateClass
    {
private:
     int               m_year;          // Year
     int               m_month;         // Month
     int               m_day;           // Day of the month
     int               m_hour;          // Hour in a day
     int               m_minute;        // Minutes
     int               m_second;        // Seconds
public:
     //--- Default constructor
                     MyDateClass(void);
     //--- Parametric constructor
                     MyDateClass(int h, int m, int s);
    };
//+------------------------------------------------------------------+
void OnStart()
    {
//---
     MyDateClass obj();
     MyDateClass *test = new MyDateClass();
    }
//+------------------------------------------------------------------+
MyDateClass::MyDateClass(void)
    {
     Print(__FUNCTION__);
    }
//+------------------------------------------------------------------+

در این مثال برای این که هر یک از دو سطر داخل OnStart Event Handling منجر به اررور نشود. باید تعریف بدنه‌ی constructor را اضافه کرد.

 

در واقع یعنی در این حالت به اررور “function ‘CFoo::CFoo’ must have a bodyبر‌می‌خوریم. :

//+------------------------------------------------------------------+
//| A class without a default constructor                            |
//+------------------------------------------------------------------+
class CFoo
    {
     string            m_name;
public:
     //--- Default constructor
                     CFoo(void);
     //--- Parametric constructor
                     CFoo(string name) { m_name = name;}
    };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
    {
//---
     CFoo badFoo[5];
    }

 

 

در مقالات بعدی آموزش ام کیو ال، مطالب آموزش کلاس در زبان MQL پی گرفته و سایر نکات مربوط به این بخش را شرح خواهیم داد.

همچنین می‌توانید از سسله مقالات آموزش Python سایت جهان بورس استفاده نمایید.

0 0 رای ها
امتیازدهی به مقاله
0 نظرات
بازخورد (Feedback) های اینلاین
مشاهده همه دیدگاه ها

مقالات پربازدید

مقالات مرتبط

سبد خرید
هیچ محصولی در سبد خرید وجود ندارد!
خرید را ادامه دهید