OOP, templates and macros in mql5, subtleties and uses - page 26

 

A question has arisen:

There is a "Program" class which uses the"New Bar" and "Data Manager" classes. The "New Bar" class in turn also uses the "Data Manager" class. Public getters and setters are implemented in the "Data Manager" class.

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;
   };

Question: What are the options for the initialization of the program for the "New Bar" class to specify the "symbol" and "timeframe" properties of the "Data Manager" class? I would not like to have public getters and setters in the New Bar class to access the data manager fields. And we'd like to keep the data manager private.

In other words: The application can use multiple classes that use the data manager. During initialization of the program, all manager fields of all classes must be initialized with required values. But I don't want to create getters in all classes to access the data manager fields. So...

 
Alexey Kozitsyn:
By your description, it makes sense to separate these settings into a separate entity, the same for all managers and beyond
 
TheXpert:
According to your description it makes sense to separate these settings into a separate entity, the same for all managers and not only

Yes, it looks like you need to inherit classes that need a manager from a base class that has getters to the manager fields. Thank you.

 
Alexey Kozitsyn:

A question has arisen:

There is a "Program" class which uses the"New Bar" and "Data Manager" classes. The "New Bar" class in turn also uses the "Data Manager" class. Public getters and setters are implemented in the "Data Manager" class.

Question: What are the options for the initialization of the program for the "New Bar" class to specify the "symbol" and "timeframe" properties of the "Data Manager" class? I would not like to have public getters and setters in the New Bar class to access the data manager fields. And we'd like to keep the data manager private.

In other words: The application can use multiple classes that use the data manager. During initialization of the program, all manager fields of all classes must be initialized with required values. But I don't want to create getters in all classes to access the data manager fields. So...

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){}
   };

That's about how I do it.

 
Vladimir Simakov:

That's roughly how I do it.

Thanks for the example, it's a bit complicated so far, but in general the idea is clear. Immediately a question arises: ok, if "one level of nesting" - here it is clear, but if there will be several levels of nesting?

Added:

It's also not clear why the cIsDelData field? After all, you can just check m_data against POINTER_DINAMIC in the destructor. Or am I wrong?

 

If you do inheritance, you will get a lot of unnecessary methods. And the object must be private. So, you will not believe, but the easiest way is to setters for all classes that use data manager.

If all data managers work with the same parameters, it is better not to create objects, but pass a pointer to one data manager. In this case, only one setter is needed to pass the pointer.

 
Alexey Kozitsyn:

Thanks for the example, it's a bit complicated so far, but in general the idea is clear. Immediately a question arises: ok, if "one level of nesting" - here it is clear, but if there will be several levels of nesting?

Added:

It's also not clear why the cIsDelData field? After all, you can just check m_data against POINTER_DINAMIC in the destructor. Or am I wrong?

No, you're wrong. You can pass a pointer to a dynamic object and, oops, kill it safely.
And about nesting. You create an instance of an object where you initially need, and only the pointers further, as in the example above. If in general it is intended to be a singleton in the project, you can make a singleton, but I've never made one using mql, so I haven't needed it, I have to try it.
 
Dmitry Fedoseev:
Vladimir Simakov:

Thank you, I will think about it.

 
Vladimir Simakov:

I'm doing it roughly like this.

what thisCDataManager* m_data line means;

Guys I want to do a thing like this. I have a macro.

#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 это дополнительное выражение которое будет дописываться в новый макрос

As a result I will have 2 macrosfoor andfoor1.

 
Seric29:

what thisCDataManager* m_data line means;

Guys I want to do a thing like this. I have a macro.

As a result I will have 2 macrosfoor andfoor1.

A pointer to an object.

No offence, but it's too early for you to deal with such macros. First of all, understand why I did this:

#define  foor1(a,b,v,g) \
for(;Funkziya(a,b,v)&&(g);(b)++)
Reason: