Как сделать?

 

Если возможно.

Работа с графическими объектами. Весь код (относительно весь): 

class cStyle{ 
   protected:
      string Name;
      long ID;   
   public:
      void Attach(string aName,long aChartID=0){
         Name=aName;
         ID=aChartID;
      }     
      void Dash(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_DASH);}      
      void DashDot(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_DASHDOT);}      
      void DashDotDot(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_DASHDOTDOT);}      
      void Dot(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_DOT);}      
      void Solid(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_SOLID);}      
}; 

class cGO{
   protected:
      string Name;
      long ID;
   public:
      cIntStyle Style;
      void Attach(string aName,long aChartID=0){
         Name=aName;
         ID=aChartID;
         Style.Attach(Name,ID);
      }
      void SetColor(color aValue){
         ObjectSetInteger(ID,Name,OBJPROP_COLOR,aValue);
      }
};



cGO g;

g.Attach("Name");
g.Style.Solid();

Класс cGO основной класс, предполагается только его использовать, в нем две общих переменных Name и ID. Применение: сначала графический объект присоединяется:

g.Attach("Name");

Затем, вызываются методы для изменения его свойств, например:

g.SetColor(Red);

  

Теперь, в чем собственно суть всего этого. Хочу, разделить методы на группы. Если хочу изменить стиль, чтобы код выглядел так:

g.Style.Solid();
g.Style.Dot();



 

Получилось, можно разделить методы на группы, но есть одно место которое не очень нравится. При присоединении графического объекта (Attach()) необходимо присоединять графический объект и к объекту Style (Style.Attach(Name,ID);). Переменные Name и ID объявленные в классе cGO не видимы из класса cStyle. Можно ли как-то так сделать, чтобы они были видимы, чтобы не приходилось для всех классов вызывать Attach() и чтобы сохранилась структрированность методов?

Разработка и реализация новых виджетов на основе класса CChartObject
Разработка и реализация новых виджетов на основе класса CChartObject
  • 2010.11.17
  • investeo
  • www.mql5.com
После написания статьи про полуавтоматический советник с графическим интерфейсом пользователя у меня возникла необходимость расширения интерфейса новым функционалом для более сложных индикаторов и экспертов. Ознакомившись с классами Стандартной библиотеки, я сделал новые виджеты. В этой статье описан процесс создания и использования новых элементов пользовательского интерфейса, созданных на базе класса CChartObjectEdit.
 

при компиляции сразу ошибки пошли, у меня вот так получилось:

class cStyle{ 
   protected:
      string Name;
      long ID;   
   public:
      void Attach(string aName,long aChartID=0){
         Name=aName;
         ID=aChartID;
      }     
      void Dash(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_DASH);}      
      void DashDot(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_DASHDOT);}      
      void DashDotDot(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_DASHDOTDOT);}      
      void Dot(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_DOT);}      
      void Solid(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_SOLID);}      
}; 

class cGO:public cStyle
{
   protected:
      string Name;
      long ID;
   public:
      cStyle cIntStyle;
      void Attach(string aName,long aChartID=0){
         Name=aName;
         ID=aChartID;
         cIntStyle.Attach(Name,ID);
      }
      void SetColor(color aValue){
         ObjectSetInteger(ID,Name,OBJPROP_COLOR,aValue);
      }
};



cGO g;

 по моему Вы перепутали имя класса и имя переменной типа класс

 
IgorM:

по моему Вы перепутали имя класса и имя переменной типа класс

Перепутал кое-что. Вот так правильно:

class cStyle{ 
   protected:
      string Name;
      long ID;   
   public:
      void Attach(string aName,long aChartID=0){
         Name=aName;
         ID=aChartID;
      }     
      void Dash(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_DASH);}      
      void DashDot(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_DASHDOT);}      
      void DashDotDot(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_DASHDOTDOT);}      
      void Dot(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_DOT);}      
      void Solid(){ObjectSetInteger(ID,Name,OBJPROP_STYLE,STYLE_SOLID);}      
}; 

class cGO{
   protected:
      string Name;
      long ID;
   public:
      cStyle Style;
      void Attach(string aName,long aChartID=0){
         Name=aName;
         ID=aChartID;
         Style.Attach(Name,ID);
      }
      void SetColor(color aValue){
         ObjectSetInteger(ID,Name,OBJPROP_COLOR,aValue);
      }
};



cGO g;

void x(){
g.Attach("s");
g.Style.Dash();
}

 

 

 

дык проблема то в чем состоит?

сейчас, в таком виде(последний Ваш код) Вы можете получить доступ к методам переменной Style, которая описана в классе cGO

если добавите наследование в класс  class cGO:public cStyle то получите напрямую доступ к методам cStyle из переменной g

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

у Вас есть два класса - объекта и они между собой никак не связаны, или Вы ищите некий способ для опережающего( forward ) описания класса? про опережающее описание ф-ций я слышал, использую в Delphi, про опережающее описание объектов даже не подозреваю такого

по моему у Вас метод  cStyle::Attach() используется как конструктор класса, если да, тогда я уже общался с представителями метаквот с просьбой обо передаче в конструктор класса параметров, но увы, было заявлено, что этого не будет  - нет в плане. Для передачи в конструктор класса параметров я использовал глобальные переменные, код конечно потерял "красоту кода", но все работало, это примерно так:

string global_Name;
long  global_ID;   

class cStyle{ 
   protected:
      string Name;
      long ID;   
   public:
      cStyle(){Name = global_Name;ID = global_ID;}
.....
перед созданием переменной типа класс cStyle Вам необходимо будет присваивать соответствующие значения переменным  global_Name и global_ID и создавать переменную типа cStyle с помощью оператора new  -тогда Вы гарантированно в том месте кода где будет new вызовете конструктор cStyle::cStyle()

 

 
IgorM:

дык проблема то в чем состоит?

1. сейчас, в таком виде(последний Ваш код) Вы можете получить доступ к методам переменной Style, которая описана в классе cGO

2. если добавите наследование в класс  class cGO:public cStyle то получите напрямую доступ к методам cStyle из переменной g

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

4. у Вас есть два класса - объекта и они между собой никак не связаны, или Вы ищите некий способ для опережающего( forward ) описания класса? про опережающее описание ф-ций я слышал, использую в Delphi, про опережающее описание объектов даже не подозреваю такого

5. по моему у Вас метод  cStyle::Attach() используется как конструктор класса, если да, тогда я уже общался с представителями метаквот с просьбой обо передаче в конструктор класса параметров, но увы, было заявлено, что этого не будет  - нет в плане. Для передачи в конструктор класса параметров я использовал глобальные переменные, код конечно потерял "красоту кода", но все работало, это примерно так:

перед созданием переменной типа класс cStyle Вам необходимо будет присваивать соответствующие значения переменным  global_Name и global_ID

1. Могу. С этим все нормально, как задумано.

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

3. Вот что-то из этой области, только хотелось бы все внутри одного класса.

4. Как бы так сказать... Класс  cStyle находится внутри класса cGO,  и хотелось бы, чтобы переменные Name и ID объявленные в cGO были видны из cStyle.

5. Предполагается несколько вариантов использования класса. 1 - для каждого графического объекта создавать эксземпляр класса (для создания панелей управления) , 2 - когда неизвестно количество графических объектов (напимер стрелки на графике как у индикатора), то в этом случае вызывается Attach(), а затем выполняется управление графическим объектом. Поэтому вопрос передачи параметров в конструктор не стоит (хотя, это было бы хорошо).

 

 

Впрочем, и так пойдет. При использовании графических объектов нет необходимости сражаться за быстродействие. Просто хотелось бы красиво сделать, если есть возможность.

Строим анализатор спектра
Строим анализатор спектра
  • 2010.10.21
  • Victor
  • www.mql5.com
Данная статья призвана познакомить читателя с возможным вариантом использования графических объектов языка MQL5. В статье рассматривается индикатор, в котором при помощи графических объектов создана панель управления простейшим анализатором спектра. Статья рассчитана на читателя, знакомого с основами языка MQL5.
 
struct chang_name{
   string Name;
   long ID;
}; 

class cStyle{ 
   protected:
      string Name;
      long ID;
      
      string externName;
      long externID;
         
   public:
      void Attach(string aName,long aChartID,chang_name &change ){
         Name=aName;
         ID=aChartID;
         externID = change.ID;
         externName = change.Name;
      }
..............

void Attach(string aName,long aChartID=0){
         Name=aName;
         ID=aChartID;
         chang_name tmp;
         tmp.ID = ID;
         tmp.Name = Name;
         Style.Attach(Name,ID,tmp);
      }
     

к сожалению возвращать в return() в качестве результата структуру mql5 напрочь отказался, поэтому придется обмениваться через переменную change которую передаем по ссылке &

ЗЫ: чет программист на форуме mql4 становится редкостью, надеюсь, что моя информация оказалась для Вас полезной, хотелось бы чтонить увидеть в своем топике https://www.mql5.com/ru/forum/130599

вот так и будем между двумя форумами прыгать )))))))))) 

Автоматическое обновление истории по всем ТФ - MQL4 форум
  • www.mql5.com
Автоматическое обновление истории по всем ТФ - MQL4 форум
 
IgorM:
к сожалению возвращать в return() в качестве результата структуру mql5 напрочь отказался, поэтому придется обмениваться через переменную change которую передаем по ссылке &

 

Не большая разница, что переменные по отдельности передавать, что структуру, всеравно надо вызывать Attach() для каждого класса объявленого внутри cGO.

Если объявить общую переменную  в модуле, ее видно из класса. Если же класс объявить внутри другого класса, то из вложенного класса не видно переменные объявленные во внешнем классе. Хотя по вызову методов видно, что один класс вложен в другой (g.Style.Dash();).

 

 

 

 

ну а как Вы хотите? если бы были конструкторы с возможностью передачи параметра в конструкторе, Вы бы могли все это сделать при инициализации экземпляра класса(переменной) cStyle Style;

этого не будет

другой вопрос, что Вы можете использовать конструктор  cGO для решения передачи параметров в cStyle, т.к. экземпляр класса cStyle Style; будет создан до вызова конструктора cGO, и тогда можно в конструкторе произвести все необходимые манипуляции по обмену данными между полями классов cStyle и cGO, конечно на количество полей в каждом классе придется не поскупиться или использовать массивы

 

 

Хочу как лучше:)

Если бы только при инициализации, то как сейчас сделано вполне нормально, не проблема, инициализация один ра выполняется. Этот класс планируется использовать еще как оболочку для управления любым графическим объектом, присоединили объект через Attach(), поуправляли им, присоединили другой... Для такого применения класса, то что сделано не самое оптимальное, из того, то может быть теоретически.

 

 

Тем или иным способом тебе придётся вложенному объекту передавать ссыли на хозяйские атрибуты.  Только лучшее будет при инициализации вложенного давать ему ссыль на самого хозяина, а не дублировать хозяйские переменные. Появляется дополнительная косвенная адресация, но есть и выигрыши. Если так сделать достигается приятный побочный эффект - можно переприцепить хозяина к другому граф-объёкту и все вложенные уже готовы к работе - их переинить не нада.   Думаю, это как раз то, чего ты и хотел. :)

Примерный набросок:                            // код компилится и, надеюсь, работает. не проверял.

class cGraphObject  // Абстрактный предок всех классов графических объектов
  {
//protected:       // протекцией придётся пожертвовать, ради торжества Мировой Графической Революции.  Лес рубят - щепки летят. (с) Иосиф.
public:
   string            Name;
   long              ID;
   void Attach(string aName,long aChartID=0)
     {
      Name=aName;
      ID=aChartID;
     }
  };
//+------------------------------------------------------------------+
class cGraphAttribute   // Абстрактный класс родоначальник всех классов графических атрибутов, 
                       // таких как длина, толщина, цвет, уровень эрекции... ;-))
  {
protected:
   cGraphObject*Own;
public:
   void Attach(cGraphObject &Owner) {Own=GetPointer(Owner);}
  };
//+------------------------------------------------------------------+
class cStyle:cGraphAttribute  // Пошли потомки.  атрибут намбер One
  {
public:
   void Dash(){ObjectSetInteger(Own.ID,Own.Name,OBJPROP_STYLE,STYLE_DASH);}
   void DashDot(){ObjectSetInteger(Own.ID,Own.Name,OBJPROP_STYLE,STYLE_DASHDOT);}
   void DashDotDot(){ObjectSetInteger(Own.ID,Own.Name,OBJPROP_STYLE,STYLE_DASHDOTDOT);}
   void Dot(){ObjectSetInteger(Own.ID,Own.Name,OBJPROP_STYLE,STYLE_DOT);}
   void Solid(){ObjectSetInteger(Own.ID,Own.Name,OBJPROP_STYLE,STYLE_SOLID);}
  };
//+------------------------------------------------------------------+
class cColor:cGraphAttribute  // Ещё один до кучи (щёб прочувствовать систему)
  {
public:
   void Set(color aValue)
     {
      ObjectSetInteger(Own.ID,Own.Name,OBJPROP_COLOR,aValue);
     }
  };
//+------------------------------------------------------------------+
class cGO:cGraphObject  // А это уже атрибутский хозяин - непосредственно конкретный графический объект
  {
public:
   cStyle            Style;
   cColor            Color;
   void Attach(string aName,long aChartID=0)
     {
      cGraphObject::Attach(aName,aChartID);
      Style.Attach(this);  // Вот таким вот макаром 
      Color.Attach(this);  // цепляешь все атрибуты
     }
  };

cGO g;  // объявим екземлярец
//+------------------------------------------------------------------+
void x()  // и поюзаем
  {
   g.Attach("s");
   g.Style.Dash();
   g.Color.Set(0xFFAA70);
  }
//+------------------------------------------------------------------+


Причина обращения: