ООП, шаблоны и макросы в mql5, тонкости и приёмы использования - страница 26

 

Возник вопрос:

Есть класс "Программа", который использует классы "Новый бар" и "Менеджер данных". Класс "Новый бар" в свою очередь также использует "Менеджер данных". В классе "Менеджер данных" реализованы публичные геттеры и сеттеры.

class CDataManager
   {
private:
    string          m_symbol;
    ENUM_TIMEFRAMES m_timeframe;
public:
    //--- Геттеры и сеттеры
   };
class CNewBar
   {
private:
    CDataManager  m_data;
   };
class СProgram
   {
private:
    CNewBar        m_newBar;
    CDataManager   m_data;
   };

Вопрос: какие есть варианты при инициализации программы у класса "Новый бар" задать свойства "символ" и "таймфрейм" класса "Менеджер данных"? Не хочется в классе "Новый бар" городить публичные геттеры и сеттеры для доступа к полям менеджера данных. Сам менеджер данных хочется при этом оставить private.

Иными словами: программа может использовать много классов, которые используют менеджер данных. А при инициализации программы нужно поля всех менеджеров всех классов инициализировать нужными значениями. Но во всех классах не хочется городить геттеры для доступа к полям менеджера данных. Как-то так...

 
Alexey Kozitsyn:
По вашему описанию логично выделить эти настройки в отдельную сущность, единую для всех менеджеров и не только
 
TheXpert:
По вашему описанию логично выделить эти настройки в отдельную сущность, единую для всех менеджеров и не только

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

 
Alexey Kozitsyn:

Возник вопрос:

Есть класс "Программа", который использует классы "Новый бар" и "Менеджер данных". Класс "Новый бар" в свою очередь также использует "Менеджер данных". В классе "Менеджер данных" реализованы публичные геттеры и сеттеры.

Вопрос: какие есть варианты при инициализации программы у класса "Новый бар" задать свойства "символ" и "таймфрейм" класса "Менеджер данных"? Не хочется в классе "Новый бар" городить публичные геттеры и сеттеры для доступа к полям менеджера данных. Сам менеджер данных хочется при этом оставить private.

Иными словами: программа может использовать много классов, которые используют менеджер данных. А при инициализации программы нужно поля всех менеджеров всех классов инициализировать нужными значениями. Но во всех классах не хочется городить геттеры для доступа к полям менеджера данных. Как-то так...

class CDataManager
   {
private:
    string          m_symbol;
    ENUM_TIMEFRAMES m_timeframe;
public:
    CDataManager():m_symbol(_Symbol),m_timeframe(_Period){}
    CDataManager(string symbol,ENUM_TIMEFRAMES frame):m_symbol(symbol),m_timeframe(frame){}
    //--- Геттеры и сеттеры
   };
class CNewBar
   {
private:
    CDataManager*  m_data;
    bool           cIsDelData;
public:
   CNewBar(CDataManager* data=NULL):m_data(!data?new CDataManager:data),cIsDelData(!data){}
   CNewBar(string symbol,ENUM_TIMEFRAMES frame):m_data(new CDataManager(symbol,frame)),cIsDelData(true){}
  ~CNewBar() {if (cIsDelData) delete m_data;}
   };
class CProgram
   {
private:
    CNewBar        m_newBar;
    CDataManager   m_data;
public:
    CProgram():m_newBar(&m_data){}
   };

Я примерно так делаю.

 
Vladimir Simakov:

Я примерно так делаю.

Спасибо за пример, немного сложновато пока, но в целом идея ясна. Сразу же возникает вопрос: ок, если "один уровень вложенности" - здесь понятно, а если будет несколько уровней вложенности?

Добавлено: 

Также не ясно, зачем поле cIsDelData? Ведь в деструкторе можно просто проверить m_data на POINTER_DINAMIC. Или я не прав?

 

Если делать наследование, то вылезет много ненужных методов. А объект-то должен быть приватным. Поэтому, не поверите, но проще всего так и сделать - сеттеры для всех классов, использующих датаменеджер.

Если все датаменеджеры работают с одинаковыми параметрами, то лучше не плодить объекты, а передавать указатель на один датаменеджер. В этом случае будет нужен только один сеттер для передачи указателя. 

 
Alexey Kozitsyn:

Спасибо за пример, немного сложновато пока, но в целом идея ясна. Сразу же возникает вопрос: ок, если "один уровень вложенности" - здесь понятно, а если будет несколько уровней вложенности?

Добавлено: 

Также не ясно, зачем поле cIsDelData? Ведь в деструкторе можно просто проверить m_data на POINTER_DINAMIC. Или я не прав?

Не правы. Вы можете передать указатель на динамический объект и, упс, благополучно убить его.
А по вложенности. Где изначально надо, там экземпляр объекта и создаете, а дальше только указатели по подобию приведенного. Если вообще в единственном числе в проекте предусматривается, то можно синглтон замутить, правда ни разу на mql не делал, необходимости не было, надо попробовать.
 
Dmitry Fedoseev:
Vladimir Simakov:

Спасибо, буду думать.

 
Vladimir Simakov:

Я примерно так делаю.

что означает эта строчка CDataManager*  m_data;

Ребята я хочу сделать такую штуку. Есть макрос 

#define foor(a,b,v) \
for(;Funkziya(a,b,v);b++)
//я хочу доработать макрос чтобы получилось так
#define foor1(a,b,v,g) \
//за основу будет взят первый макрос
for(;Funkziya(a,b,v)&&g;b++)//эффект должен быть такой где g это дополнительное выражение которое будет дописываться в новый макрос

В результате у меня будет 2 макроса foor и foor1.

 
Seric29:

что означает эта строчка CDataManager*  m_data;

Ребята я хочу сделать такую штуку. Есть макрос 

В результате у меня будет 2 макроса foor и foor1.

Указатель на объект.

Без обид, но с подобными макросами Вам еще рано, нахлебаетесь. Для начала поймите, зачем я вот так сделал:

#define foor1(a,b,v,g) \
for(;Funkziya(a,b,v)&&(g);(b)++)
Причина обращения: