Как передать структуры в конструктор класса?

 

Всех с наступающими праздниками!

Оказывается ограничение на кол-во параметром конструктора класса составляет 63 переменные: https://www.mql5.com/ru/forum/1111/page3269#comment_43667806.

Форумчание справедливо заметили, что можно легко запутаться, если такое большое кол-во параметров записывать на вход конструктора.

Я действительно постоянно путался, а потом и вовсе упёрся в ограничение х63.

Подскажите, как вписать на вход конструктора структуру, содержащую в себе параметры?

Вот условный пример кода, где на входе конструктора хотелось бы получить POS1 и POS2 вместо кучи параметров.

Пробовал разные варианты С++ из интернета, но компилятор постоянно ругается..

P.S. я использую список экземпляров класса, поэтому в примере список тоже присутствует.

#include <Arrays\List.mqh>        // Для списка объектов класса cPTRK 

// входные параметры
ulong           curntDealTicket =1;
ENUM_TIMEFRAMES TF1             =PERIOD_M15;
ENUM_TIMEFRAMES TF2             =PERIOD_M30;
double          Part1           =0.25;
double          Part2           =0.5;
double          SLS             =0;
color           color1          =clrRed;
color           color2          =clrYellow;
datetime        CurrentDealTime =0;
int             L_min_filter_p1 =1;
int             L_min_filter_p2 =1;
double          K_FractalDelta1 =0.1;
double          K_FractalDelta2 =0.2;
bool            breakeven       =true;
double          BreakevenLev    =0.1;
uint            LminShift1      =1;
uint            LminShift2      =2;

struct PosTrackParams
  {
   ulong             st_ticket;
   ENUM_TIMEFRAMES   st_TF;
   double            st_Part;
   double            st_SL;
   color             st_ObjColor;
   datetime          st_CurrentDealTime;
   int               st_L_min_filter_p;
   double            st_K_FractalDelta;
   bool              st_Breakeven;
   double            st_BreakevenLev;
   uint              st_LminShift;
  };

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   PosTrackParams POS1;

   POS1.st_ticket          = curntDealTicket;
   POS1.st_TF              = TF1;
   POS1.st_Part            = Part1;
   POS1.st_SL              = SLS;
   POS1.st_ObjColor        = color1;
   POS1.st_CurrentDealTime = CurrentDealTime;
   POS1.st_L_min_filter_p  = L_min_filter_p1;
   POS1.st_K_FractalDelta  = K_FractalDelta1;
   POS1.st_Breakeven       = breakeven;
   POS1.st_BreakevenLev    = BreakevenLev;
   POS1.st_LminShift       = LminShift1;

   PosTrackParams POS2;

   POS2.st_ticket          = curntDealTicket;
   POS2.st_TF              = TF2;
   POS2.st_Part            = Part2;
   POS2.st_SL              = SLS;
   POS2.st_ObjColor        = color2;
   POS2.st_CurrentDealTime = CurrentDealTime;
   POS2.st_L_min_filter_p  = L_min_filter_p2;
   POS2.st_K_FractalDelta  = K_FractalDelta2;
   POS2.st_Breakeven       = breakeven;
   POS2.st_BreakevenLev    = BreakevenLev;
   POS2.st_LminShift       = LminShift2;

   CList*        list;
   cPTRK*        PTRK;

   int PTRK_Instance=-1; // позиция экземпляра класса cPTRK в списке

   PTRK_Instance = list.Add(new cPTRK(
                               POS1.st_ticket, POS1.st_TF, POS1.st_Part, POS1.st_SL, POS1.st_ObjColor, POS1.st_CurrentDealTime,
                               POS1.st_L_min_filter_p, POS1.st_K_FractalDelta, POS1.st_Breakeven, POS1.st_BreakevenLev, POS1.st_LminShift,
                               POS2.st_ticket, POS2.st_TF, POS2.st_Part, POS2.st_SL, POS2.st_ObjColor, POS2.st_CurrentDealTime,
                               POS2.st_L_min_filter_p, POS2.st_K_FractalDelta, POS2.st_Breakeven, POS2.st_BreakevenLev, POS2.st_LminShift));

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class cPTRK : public CObject
  {
private:

   struct PTrackParams
     {
      ulong             st_ticket;           
      ENUM_TIMEFRAMES   st_TF;               
      double            st_Part;             
      double            st_Vol;              
      double            st_SL;               
      color             st_ObjColor;        
      datetime          st_CurrentDealTime;  
      int               st_L_min_filter_p;   
      double            st_K_FractalDelta;   
      bool              st_Breakeven;        
      double            st_BreakevenLev;     
      uint              st_LminShift;        
     };

   //    Объявление структур
   PTrackParams      PTrackTF1;
   PTrackParams      PTrackTF2;

public:
                     cPTRK(
      ulong x1ticket, ENUM_TIMEFRAMES x1TF, double x1Part, double x1SL,  color x1ObjColor, datetime x1CurrentDealTime,
      int x1L_min_filter_p, double x1K_FractalDelta, bool x1Breakeven, double x1BreakevenLev, uint x1LminShift,
      ulong x2ticket, ENUM_TIMEFRAMES x2TF, double x2Part, double x2SL,  color x2ObjColor, datetime x2CurrentDealTime,
      int x2L_min_filter_p, double x2K_FractalDelta, bool x2Breakeven, double x2BreakevenLev, uint x2LminShift)

     {
      //Зададим структуру для TF1
      PTrackTF1.st_ticket          = x1ticket;
      PTrackTF1.st_TF              = x1TF;
      PTrackTF1.st_Part            = x1Part;
      PTrackTF1.st_Vol             = 0;
      PTrackTF1.st_SL              = x1SL;
      PTrackTF1.st_ObjColor        = x1ObjColor;
      PTrackTF1.st_CurrentDealTime = x1CurrentDealTime;
      PTrackTF1.st_L_min_filter_p  = x1L_min_filter_p;
      PTrackTF1.st_K_FractalDelta  = x1K_FractalDelta;
      PTrackTF1.st_Breakeven       = x1Breakeven;
      PTrackTF1.st_BreakevenLev    = x1BreakevenLev;
      PTrackTF1.st_LminShift       = x1LminShift;
      
      //Зададим структуру для TF2
      PTrackTF2.st_ticket          = x2ticket;
      PTrackTF2.st_TF              = x2TF;
      PTrackTF2.st_Part            = x2Part;
      PTrackTF2.st_Vol             = 0;
      PTrackTF2.st_SL              = x2SL;
      PTrackTF2.st_ObjColor        = x2ObjColor;
      PTrackTF2.st_CurrentDealTime = x2CurrentDealTime;
      PTrackTF2.st_L_min_filter_p  = x2L_min_filter_p;
      PTrackTF2.st_K_FractalDelta  = x2K_FractalDelta;
      PTrackTF2.st_Breakeven       = x2Breakeven;
      PTrackTF2.st_BreakevenLev    = x2BreakevenLev;
      PTrackTF2.st_LminShift       = x2LminShift;
     }

                    ~cPTRK() //деструктор
     {
     }

  };
//+------------------------------------------------------------------+
Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • 2022.12.06
  • www.mql5.com
Общее обсуждение: Ошибки, баги, вопросы
 
Как в любой метод, структура передаётся по ссылке.
 
Sergey Gridnev #:
Как в любой метод, структура передаётся по ссылке.

А что делать с типом данных?

Компилятор намекнул про ссылку, но у меня какой-то затык.
 
Sunriser #:

А что делать с типом данных?

Компилятор намекнул про ссылку, но у меня какой-то затык.
&
 
Конструктор:
cPTRK(PosTrackParams &params1, PosTrackParams &params2) {
// Тут код.
// Доступ к параметрам:
// psrams1.st_ticket
// и т.д
}

Вообще, для структур простых типов доступно копирование через операцию присваивания. Т.е. не надо присваивать значение каждому члену, можно все значения структуры присвоить значениям другой структуры.
 

Спасибо!

Решение:

// входные параметры
ulong           curntDealTicket =1;
ENUM_TIMEFRAMES TF1             =PERIOD_M15;
ENUM_TIMEFRAMES TF2             =PERIOD_M30;
double          Part1           =0.25;
double          Part2           =0.5;
double          SLS             =0;
color           color1          =clrRed;
color           color2          =clrYellow;
datetime        CurrentDealTime =0;
int             L_min_filter_p1 =1;
int             L_min_filter_p2 =1;
double          K_FractalDelta1 =0.1;
double          K_FractalDelta2 =0.2;
bool            breakeven       =true;
double          BreakevenLev    =0.1;
uint            LminShift1      =1;
uint            LminShift2      =2;

struct PosTrackParams
  {
   ulong             st_ticket;
   ENUM_TIMEFRAMES   st_TF;
   double            st_Part;
   double            st_SL;
   color             st_ObjColor;
   datetime          st_CurrentDealTime;
   int               st_L_min_filter_p;
   double            st_K_FractalDelta;
   bool              st_Breakeven;
   double            st_BreakevenLev;
   uint              st_LminShift;
  };

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   PosTrackParams POS1;

   POS1.st_ticket          = curntDealTicket;
   POS1.st_TF              = TF1;
   POS1.st_Part            = Part1;
   POS1.st_SL              = SLS;
   POS1.st_ObjColor        = color1;
   POS1.st_CurrentDealTime = CurrentDealTime;
   POS1.st_L_min_filter_p  = L_min_filter_p1;
   POS1.st_K_FractalDelta  = K_FractalDelta1;
   POS1.st_Breakeven       = breakeven;
   POS1.st_BreakevenLev    = BreakevenLev;
   POS1.st_LminShift       = LminShift1;

   PosTrackParams POS2;

   POS2.st_ticket          = curntDealTicket;
   POS2.st_TF              = TF2;
   POS2.st_Part            = Part2;
   POS2.st_SL              = SLS;
   POS2.st_ObjColor        = color2;
   POS2.st_CurrentDealTime = CurrentDealTime;
   POS2.st_L_min_filter_p  = L_min_filter_p2;
   POS2.st_K_FractalDelta  = K_FractalDelta2;
   POS2.st_Breakeven       = breakeven;
   POS2.st_BreakevenLev    = BreakevenLev;
   POS2.st_LminShift       = LminShift2;

   cPTRK*        PTRK;

   PTRK=  new cPTRK(POS1, POS2);

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class cPTRK
  {
private:

   //    Объявление структур
   PosTrackParams      PTrackTF1;
   PosTrackParams      PTrackTF2;

public:
                     cPTRK(const PosTrackParams &_PTrackTF1, const PosTrackParams &_PTrackTF2)

     {
      //Скопируем структуру для TF1 (вариант 1)
      PTrackTF1=_PTrackTF1;

      //Зададим структуру для TF2 поэлементным копированием (вариант 2)
      PTrackTF2.st_ticket          = _PTrackTF2.st_ticket;
      PTrackTF2.st_TF              = _PTrackTF2.st_TF;
      PTrackTF2.st_Part            = _PTrackTF2.st_Part;
      PTrackTF2.st_SL              = _PTrackTF2.st_SL;
      PTrackTF2.st_ObjColor        = _PTrackTF2.st_ObjColor;
      PTrackTF2.st_CurrentDealTime = _PTrackTF2.st_CurrentDealTime;
      PTrackTF2.st_L_min_filter_p  = _PTrackTF2.st_L_min_filter_p;
      PTrackTF2.st_K_FractalDelta  = _PTrackTF2.st_K_FractalDelta;
      PTrackTF2.st_Breakeven       = _PTrackTF2.st_Breakeven;
      PTrackTF2.st_BreakevenLev    = _PTrackTF2.st_BreakevenLev;
      PTrackTF2.st_LminShift       = _PTrackTF2.st_LminShift;

      //Проверим результат
      Print("PTrackTF1.st_TF: ", EnumToString(PTrackTF1.st_TF));
      Print("PTrackTF2.st_TF: ", EnumToString(PTrackTF2.st_TF));
     }

                    ~cPTRK() //деструктор
     {
     }

  };
//+------------------------------------------------------------------+
 
Sunriser:

Всех с наступающими праздниками!

Оказывается ограничение на кол-во параметром конструктора класса составляет 63 переменные: https://www.mql5.com/ru/forum/1111/page3269#comment_43667806.

Форумчание справедливо заметили, что можно легко запутаться, если такое большое кол-во параметров записывать на вход конструктора.

Я действительно постоянно путался, а потом и вовсе упёрся в ограничение х63.

Подскажите, как вписать на вход конструктора структуру, содержащую в себе параметры?

Вот условный пример кода, где на входе конструктора хотелось бы получить POS1 и POS2 вместо кучи параметров.

Пробовал разные варианты С++ из интернета, но компилятор постоянно ругается..

P.S. я использую список экземпляров класса, поэтому в примере список тоже присутствует.

Передача огромного количества параметров в функцию считается крайне плохим паттерном программирования. Если честно, не понятно вообще что вы хотели сделать в этом коде. Если выхотите что то передать через структуру, тобычно, ее обьявляют в отдельном файле, например, types.mqh, а потом подключают где это нужно:

types.mqh:

struct SomeParameters
{
  double param1;
  double param2;
  .....
  string param_n;
};

some_class.mqh:

#include "types.mqh"

class SomeClass
{
public:
  SomeClass(const SomeParameters& conf)
    :  _conf(conf)
  {
  }
  ~SomeClass() {}
private:
  SomeParameters _conf;
};

Но как правило, подобные вещи передаются в отдельном методе, например, bool init(const SomeParameters& conf), по скольку в конструкторе вы не можете проконтролировать валидность входных данных. 

Второй вариант, установка параметров осуществляется через set'теры:

class SomeClass
{
public:
  SomeClass() {}
 ~SomeClass() {}
  
  SomeClass* set_parameters_1(...) {  ...; return &this; }
  SomeClass* set_parameters_2(...) { ...; return &this; }
};
Причина обращения: