Вопросы по ООП (Объектно Ориентированному Программированию ) - страница 5

 
VOLDEMAR:

сейчас я переделал свой класс

class vr_trade
  {
private:
   int               openorders(string sy,int typ,double lot,double price);
   string            tip(int typ);
   int               m_magic;
   int               m_slip;
public:
   int               Buy(string sy,double lot);
   int               Sel(string sy,double lot);
   int               BuyLimit(string sy,double lot,double price);
   int               SelLimit(string sy,double lot,double price);
   int               BuyStop(string sy,double lot,double price);
   int               SelStop(string sy,double lot,double price);
   void              MagSlip(int mag=-1,int slip=0);
   vr_MarketInfo    *Log;
                     vr_trade();
                    ~vr_trade();
  };
MqlTick st;
//+------------------------------------------------------------------+
vr_trade:: vr_trade()
  {
   Log=new vr_MarketInfo;
   MagSlip(-1,0);
  }
И добавил наследование ... ( Подозреваю что могу ошибаться ) из класса vr_MarketInfo

класс vr_MarketInfo возвращает инфу о Point, Digits для символа а так же проверяет лот на ошибки, и многое другое необходимое мне для работы в том числе ведет лог в екселе и на чарте

При использовании метода как Выше выдается список при работе в советнике Primer.Primer.Primer()

Я бы хотел делать как то более сокращенно все...

Где наследование? Какой смысл в указателе?

 
Zhunko:

Где наследование? Какой смысл в указателе?


Напишите учебник по MQL4+. Скооперируйтеь, знатоки, и напишите. 50 баков дам :)
 
А ведь на самом деле, если по факту, то в учебнике, да и в документации, никакой канкретики нет по ни по поводу применения указателей, ни по поводу оператора new. Остаётся то ли гадать, то ли ждать с моря погоды. Или когда типа случайно где-то что-то кто-то скажет. Я вообще в шоке, как так получается. Ещё интересно, что кроме меня и топикстартера ВЛадимира никому как-будто ничего не нужно. Хотя я больше всё-таки полагаю, что многие совсем не втыкают в эту тему. А потому и не лезут в подобные вопросы..
 
tara:

Напишите учебник по MQL4+. Скооперируйтеь, знатоки, и напишите. 50 баков дам :)

Всё давно написано.

MQL4 == C++ с небольшими ограничениями.

 
hoz:
А ведь на самом деле, если по факту, то в учебнике, да и в документации, никакой канкретики нет по ни по поводу применения указателей, ни по поводу оператора new. Остаётся то ли гадать, то ли ждать с моря погоды. Или когда типа случайно где-то что-то кто-то скажет. Я вообще в шоке, как так получается. Ещё интересно, что кроме меня и топикстартера ВЛадимира никому как-будто ничего не нужно. Хотя я больше всё-таки полагаю, что многие совсем не втыкают в эту тему. А потому и не лезут в подобные вопросы..


Какая конкретика нужна? Везде действует один принцип: все надо делать как можно проще. Не надо лезть в дебри только ради того чтобы быть в дебрях. Если задачу можно решить просто, то ее и надо решать просто.

Динамические указатели нужны, если в прорамме требуется динамическая работа с объектами: создание, удалене в процесе работы программы. Если заранее известно какие объекты и в каком количестве потребуются в программе, то и не нужны динамическеи указатели. Но за исключением случая, когда очень много обюъектов, в этом случае их проще создать в цикле через new.


 
VOLDEMAR:
Мне например тяжело изучать теорию, продемонстрируйте пример, и распишите как функции определит круг, квадрат, трапецию, или треугольник ???

В одной из статей, ссылки на которые приведены в первом посте есть такой пример.

Базовый класс c виртуальным методом. В потомке одноименный метод, в которjм собствено и делаются вычисления.

 
VOLDEMAR:
Мне например тяжело изучать теорию, продемонстрируйте пример, и распишите как функции определит круг, квадрат, трапецию, или треугольник ???


Трапецию и треугольник оставляю на самостоятельную работу:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CShape
  {
  
public:
   virtual string Type()      { return(""); }
   virtual double Perimeter() { return(-1); }
   virtual double Square()    { return(-1); }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CCircle : public CShape
  {
   double         m_r;
  
public:
                  CCircle(double r):m_r(r) { }
   virtual string Type()      { return("circle");     }
   virtual double Perimeter() { return(2*M_PI*m_r);   }
   virtual double Square()    { return(M_PI*m_r*m_r); }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CRectangle : public CShape
  {
   double         m_a;   
   double         m_b;
   
public:
                  CRectangle(double a,double b):m_a(a),m_b(b) { }
   virtual string Type()      { return("rectangle");  }
   virtual double Perimeter() { return(m_a*2+m_b*2);  }
   virtual double Square()    { return(m_a*m_b);      }   
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   CShape *shape[10];
//--- создаём объекты
   for(int n=0;n<10;n++)
     {
      if((MathRand()&1)==1)
         shape[n]=new CCircle(MathRand()%10+1);
      else
         shape[n]=new CRectangle(MathRand()%10+1,MathRand()%10+1);
     }
//--- выводим данные по объектам
   for(int n=0;n<10;n++)
      PrintFormat("%s p=%.3f s=%.3f",shape[n].Type(),shape[n].Perimeter(),shape[n].Square());
//--- удаляем объекты
   for(int n=0;n<10;n++)
      delete shape[n];
  }
//+------------------------------------------------------------------+
 
Integer:

Динамические указатели ну;ys, если в прорамме требуется динамическая работа с объектами: создание, удалене в процесе работы программы. Если заранее известно какие объекты и в каком количестве потребуются в программе, то и не нужны динамическеи указатели. Но за исключением случая, когда очень много обюъектов, в этом случае их проще создать в цикле через new.

Точно! И даже в этом случае можно обойтись без указателей.
 
VOLDEMAR:
#property strict
input int Slip=30;
input int Magic=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
class vr_trade
  {
private:
   int               openorders(string sy,int typ,double lot,double price);
   string            tip(int typ);
public:
   int               Buy(string sy,double lot);
   int               Sel(string sy,double lot);
   int               BuyLimit(string sy,double lot, double price);
   int               SelLimit(string sy,double lot, double price);
   int               BuyStop(string sy,double lot, double price);
   int               SelStop(string sy,double lot, double price);
                     vr_trade(){}
                    ~vr_trade(){}
  };
MqlTick st;
vr_trade trade;
//+------------------------------------------------------------------+
void OnTick()
  {
trade.Buy("EURUSD",0.01); // Пример открытия позиции возвращающей тиккет ордера.
  }
//+------------------------------------------------------------------+  
int vr_trade :: Buy(string sy,double lot)
{
return openorders(sy,0,lot);
}
//+------------------------------------------------------------------+  
int vr_trade :: Sel(string sy,double lot)
{
return openorders(sy,1,lot);
}
//+------------------------------------------------------------------+  
int vr_trade :: BuyLimit(string sy,double lot, double price)
{
return openorders(sy,2,lot,price);
}
//+------------------------------------------------------------------+  
int vr_trade :: SelLimit(string sy,double lot, double price)
{
return openorders(sy,3,lot,price);
}
//+------------------------------------------------------------------+  
int vr_trade :: BuyStop(string sy,double lot, double price)
{
return openorders(sy,4,lot,price);
}
//+------------------------------------------------------------------+  
int vr_trade :: SelStop(string sy,double lot, double price)
{
return openorders(sy,5,lot,price);
}
//+------------------------------------------------------------------+
int vr_trade :: openorders(string sy="",int typ=0,double lot=0,double price=0)
  {
   int tik=-2;
   double di=NormalizeDouble(500*_Point,_Digits);
   if(sy==""){sy=_Symbol;Print("Установлен символ текущего графика ",sy);}
   if(lot<MarketInfo(sy,MODE_MINLOT)){lot=MarketInfo(sy,MODE_MINLOT); Print("Советник скорректировал лот ",lot);}
   if(!SymbolInfoTick(sy,st))Print("Не удалось прогрузить цены для символа ",sy);
   if(price==0)//Даблы так лучше не сравнивать.
     {
      if(typ==0)price=st.ask;
      if(typ==1)price=st.bid;
      if(typ==2)price=st.ask-di;
      if(typ==3)price=st.bid+di;
      if(typ==4)price=st.ask+di;
      if(typ==5)price=st.bid-di;
     }
   if(IsTradeAllowed()==true)
     {
      RefreshRates();
      tik=OrderSend(sy,typ,lot,price,Slip,0,0,"",Magic,0,clrRed);
      if(tik>0)Print("Успешно открыт ордер Ticket ",tik," Typ ",tip(typ)," Symbol ",sy," Lot ",lot," Price ",price);
      else Print("Ошибка открытия ордера N",GetLastError());
     }
   else
      Print("Торговый поток занят");
   return tik;
  }
//+------------------------------------------------------------------+
string vr_trade :: tip(int typ ENUM_ORDER_TYPE type)
  {
   string txt="";
   switch(typ)
     {
      case 0: txt="BUY";        break;
      case 1: txt="SELL";       break;
      case 2: txt="BUY LIMIT";  break;
      case 3: txt="SELL LIMIT"; break;
      case 4: txt="BUY STOP";   break;
      case 5: txt="SELL STOP";  break;
      default : txt="Ошибка типа ордера";
     }
   return txt;
  }
//+------------------------------------------------------------------+


У вас класс на 90% избыточен. Основную работу выполняют только две функции, это openorders и tip Зачем Вы используйте Sel, Buy SelStop и т.д., если фактически все они лишь вызывают Openorders? Далее тип ордера передается как int а значит не защищен. Вместо int лучше использовать либо свое перечисление, либо стандартное ENUM_ORDER_TYPE. И вообще лучше никогда не исопльзуйте магические цифры "1", "2" и т.д., только перечисления. Это не даст заслать в функцию левое значение ордера. Cама функция Openorders слишком большая. Очевидно что она состоит из двух блоков, блока заключения сделки и блока проверки условий. Каждый из них должен быть в виде отдельной приватной функции.

Для начала не плохо, но еще многому надо учиться. Функцию tip лучше переписать так:

string vr_trade::tip(ENUM_ORDER_TYPE orderType)
{
   return EnumToString(orderType);
}
 
Integer:


Какая конкретика нужна? Везде действует один принцип: все надо делать как можно проще. Не надо лезть в дебри только ради того чтобы быть в дебрях. Если задачу можно решить просто, то ее и надо решать просто.

Динамические указатели нужны, если в прорамме требуется динамическая работа с объектами: создание, удалене в процесе работы программы. Если заранее известно какие объекты и в каком количестве потребуются в программе, то и не нужны динамическеи указатели. Но за исключением случая, когда очень много обюъектов, в этом случае их проще создать в цикле через new.

Указатели не заменимы при сложных преобразованиях объектов, когда необходима динамическая идентификация типов.
Причина обращения: