OOP, modelos e macros em mql5, sutilezas e usos - página 26

 

Surgiu uma pergunta:

Há uma classe "Programa" que usa as classes"Nova Barra" e "Gerenciador de Dados". A classe "Nova Barra", por sua vez, também usa a classe "Gerenciador de Dados". Os getters e setters públicos são implementados na classe "Data Manager".

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

Pergunta: Quais são as opções para a inicialização do programa da classe "Nova Barra" para especificar as propriedades "símbolo" e "prazo" da classe "Gerenciador de Dados"? Eu não gostaria de ter getters e setters públicos na classe New Bar para acessar os campos de gerenciamento de dados. E gostaríamos de manter o gerente de dados privado.

Em outras palavras: A aplicação pode utilizar várias classes que utilizam o gerenciador de dados. Durante a inicialização do programa, todos os campos de gerência de todas as classes devem ser inicializados com valores requeridos. Mas eu não quero criar getters em todas as classes para acessar os campos do gerenciador de dados. Então...

 
Alexey Kozitsyn:
Pela sua descrição, faz sentido separar estas configurações em uma entidade separada, a mesma para todos os gerentes e além
 
TheXpert:
De acordo com sua descrição, faz sentido separar essas configurações em uma entidade separada, a mesma para todos os gerentes e não apenas

Sim, parece que você precisa herdar classes que precisam de um gerente de uma classe de base que tenha getters para os campos de gerente. Obrigado.

 
Alexey Kozitsyn:

Surgiu uma pergunta:

Há uma classe "Programa" que usa as classes"Nova Barra" e "Gerenciador de Dados". A classe "Nova Barra", por sua vez, também usa a classe "Gerenciador de Dados". Os getters e setters públicos são implementados na classe "Data Manager".

Pergunta: Quais são as opções para a inicialização do programa da classe "Nova Barra" para especificar as propriedades "símbolo" e "prazo" da classe "Gerenciador de Dados"? Eu não gostaria de ter getters e setters públicos na classe New Bar para acessar os campos de gerenciamento de dados. E gostaríamos de manter o gerente de dados privado.

Em outras palavras: A aplicação pode utilizar várias classes que utilizam o gerenciador de dados. Durante a inicialização do programa, todos os campos de gerência de todas as classes devem ser inicializados com valores requeridos. Mas eu não quero criar getters em todas as classes para acessar os campos do gerenciador de dados. Então...

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

É assim que eu faço.

 
Vladimir Simakov:

É mais ou menos assim que eu o faço.

Obrigado pelo exemplo, é um pouco complicado até agora, mas em geral a idéia é clara. Surge imediatamente uma pergunta: ok, se "um nível de nidificação" - aqui está claro, mas se haverá vários níveis de nidificação?

Adicionado:

Também não está claro porque o campo cIsDelData? Afinal de contas, você pode simplesmente verificar m_data contra POINTER_DINAMIC no destruidor. Ou eu estou errado?

 

Se você fizer herança, você terá muitos métodos desnecessários. E o objeto deve ser privado. Portanto, você não vai acreditar, mas a maneira mais fácil é definir os responsáveis por todas as classes que utilizam o gerenciador de dados.

Se todos os gerentes de dados trabalham com os mesmos parâmetros, é melhor não criar objetos, mas passar um ponteiro para um gerente de dados. Neste caso, apenas um setter é necessário para passar o ponteiro.

 
Alexey Kozitsyn:

Obrigado pelo exemplo, é um pouco complicado até agora, mas em geral a idéia é clara. Surge imediatamente uma pergunta: ok, se "um nível de nidificação" - aqui está claro, mas se haverá vários níveis de nidificação?

Adicionado:

Também não está claro por que o campo cIsDelData? Afinal de contas, você pode simplesmente verificar m_data contra POINTER_DINAMIC no destruidor. Ou eu estou errado?

Não, você está errado. Você pode passar um ponteiro para um objeto dinâmico e, oops, matá-lo com segurança.
E sobre a nidificação. Você cria uma instância de um objeto onde você inicialmente precisa, e apenas as indicações mais adiante, como no exemplo acima. Se em geral se pretende ser um singleton no projeto, você pode fazer um singleton, mas eu nunca fiz um usando mql, então eu não precisei, eu tenho que tentar.
 
Dmitry Fedoseev:
Vladimir Simakov:

Obrigado, vou pensar sobre isso.

 
Vladimir Simakov:

Estou fazendo isso mais ou menos assim.

o que esta linhaCDataManager* m_data significa;

Caras, eu quero fazer uma coisa assim. Eu tenho uma 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 это дополнительное выражение которое будет дописываться в новый макрос

Como resultado, eu terei 2 macrosfoor efoor1.

 
Seric29:

o que esta linhaCDataManager* m_data significa;

Caras, eu quero fazer uma coisa assim. Eu tenho uma macro.

Como resultado, eu terei 2 macrosfoor efoor1.

Um ponteiro para um objeto.

Sem ofensa, mas é muito cedo para você lidar com tais macros. Antes de mais nada, entenda porque fiz isto:

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