É possível implementar um padrão de um único botão na MQL4. - página 9

 
hoz:

Eu o fiz desta maneira:

Mas, por alguma razão, há muitos erros na compilação. O que está errado?

Tentar transferir um Singleton bastante simples da Myers para a MQL4+++ poderia parecer assim, por exemplo:

#property strict

/******************************************************************************/
class Symbol_Properties {
private:
   // Реализация технической части singleton'а
  /******************************************************************************/
public: // Вечно в этом MQL4++ что-то не работает: 'Symbol_Properties::Symbol_Prope…' - cannot call private member function
  Symbol_Properties() {};
private: // Восстанавливаем private
  Symbol_Properties(const Symbol_Properties &p);
  void operator =(const Symbol_Properties &);

public:
  static Symbol_Properties *singleton() {
    static Symbol_Properties sp;
    return GetPointer(sp);
  }

  // Пользовательская часть singleton'а
  /******************************************************************************/
  datetime    gdt_Quote;           // Время поступления последней котировки
  double      gda_Price [2];       // Текущие рыночные цены (0 - Bid, 1- Ask)
  double      gd_Spread;           // Размер спреда в пунктах
  double      gd_Swap;             // Своп
  double      gd_Comission;        // Комиссия
  double      gd_Pt;               // Величина одного пункта
  int         gi_Digits;           // Количество знаков в цене после запятой
  int         gi_StopLevel;        // Минимально-допустимый уровень стоп-лосса/тейк-профита в пунктах
  int         gi_FreezLevel;       // Уровень заморозки ордеров в пунктах
};

/******************************************************************************/
void change() {
  Symbol_Properties *p = Symbol_Properties::singleton(); // Получение singleton'а

  p.gdt_Quote = TimeCurrent();
  p.gda_Price[0] = Bid;
  p.gda_Price[1] = Ask;
}

/******************************************************************************/
void OnStart() {
  Symbol_Properties *p = Symbol_Properties::singleton(); // Получение singleton'а

  Print("gdt_Quote = ", p.gdt_Quote, ", Price = ", p.gda_Price[0], "/", p.gda_Price[1]);
  change();
  Print("gdt_Quote = ", p.gdt_Quote, ", Price = ", p.gda_Price[0], "/", p.gda_Price[1]);
}

Resultado da execução:

01:24:57 Script 3 EURUSDm,H1: loaded successfully
01:24:57 3 EURUSDm,H1: initialized
01:24:57 3 EURUSDm,H1: gdt_Quote = 1970.01.01 00:00:00, Price = 0.0/0.0
01:24:57 3 EURUSDm,H1: gdt_Quote = 2014.09.03 21:24:57, Price = 1.31461/1.3148
01:24:57 3 EURUSDm,H1: uninit reason 0
01:24:57 Script 3 EURUSDm,H1: removed

Um método estático singleton() cria uma variável estática do tipo Symbol_Properties, mas no momento da compilação é gerado um erro de acesso de chamada do construtor NÃO válido, porque o método, embora estático, - tem acesso a todos os membros, incluindo particulares. Portanto, devido a um bug na implementação da MQL4++, este construtor teve que ser colocado em público. Se eles o consertarem, não teremos mais que fazer isso.

O resultado da execução mostra que os dados mudaram após a mudança() chamada. Isto indica indiretamente que a função Change() recebeu o endereço do mesmo objeto dentro de si que também foi recebido em OnStart().

Devido ao erro na MQL4++, isto não é nenhum Singleton, uma vez que o construtor padrão é público, por isso muitos desses objetos podem ser criados. Se o erro for corrigido, e após o construtor padrão ser colocado na seção privada, ele se tornará uma implementação completa do Myers Singleton na MQL4++.

 
ALXIMIKS:

Você não descobriu em dois dias que a estática se comporta de maneira diferente em estudos e classe?

as estruturas parecem ter sido tiradas de c e apenas um pouco mais elevadas em termos de herança,

Quanto às aulas, elas são de pleno direito.

Por causa disso, você não precisa reservar espaço para uma variável estática em estruturas

mas você tem que reservar espaço nas aulas, caso contrário, não o fará:

Não é verdade, este maravilhoso compilador MQL4++ se comporta de maneira diferente. Assim que você cria uma instância de objeto, o comportamento "alinha":

#property strict

/******************************************************************************/
struct A {
  static int x;
};

/******************************************************************************/
void OnStart() {
  A y;
}

Por alguma razão não se compila (o primeiro e o terceiro são advertências, mas o segundo é um erro de pleno direito):

struct has no members, size assigned to 1 byte
unresolved static variable 'A::x'
variable 'y' not used

Então, é necessário reservar "espaço para uma variável estática" em estruturas?

E na próxima versão do terminal/compilador - será o mesmo (bem, não se apressar para consertar tudo o que foi escrito antes ao mudar a versão)?

 
TheXpert:

Esqueci do encapsulamento. E pode ser apagado. E aqui não há indicações constantes). Na verdade, o singleton não é o melhor padrão.

E os modelos são bons, pelo menos alguns são. Para as aulas, provavelmente apenas um sonho.



Bem, quer seja o pior ou o melhor, não julgarei.

Deixe-me lembrar aos participantes da discussão que os MEMORY MANAGEMENT MODES acima mencionados - Automático, Dinâmico, Estático, Baseado - não se aplicam aos modelos, não importa o quão poderoso seja o OOP.

 
Так обязательно ли резервировать в структурах "место под static-переменную"?
"Sim", é apenas um ponto que você também pode fazer "não", mas não deve fazer dessa maneira.
 
simpleton:


Agora, por causa do bug no MQL4++, isto não é um Singleton, porque muitos desses objetos podem ser criados, porque o construtor padrão é público. Se o erro for corrigido e o construtor padrão for colocado na seção privada, ele se tornará uma implementação completa de Singleton na MQL4++.


Obrigado, eu não sabia que podia pegar um ponteiro aqui.

O código é confuso, poderia ser mais simples, lamentamos que não existam modelos.

Eu não posso colocar o código ((

classe Singleton{

privado:

classe SomeClass{

público:

int a;

};

Singleton(){}

~Singleton(){}

público:

estática de alguma classe* Instância(){

estática de alguma classe a();

retornar GetPointer (a);

}

};

nulo OnStart()

{

SomeClass* some_ptr = Singleton::Instance();

some_ptr.a = 5;

Alerta(some_ptr.a);

}

 
ALXIMIKS:


Obrigado, não sabia que você podia pegar um ponteiro aqui.

Você está mexendo com o código, poderia ser mais simples, lamento que não existam modelos.

Eu não consigo fazer o código funcionar ((

classe Singleton{

privado:

classe SomeClass{

público:

int a;

};

Singleton(){}

~Singleton(){}

público:

estática de alguma classe* Instância(){

estática de alguma classe a();

retornar GetPointer (a);

}

};

nulo OnStart()

{

SomeClass* some_ptr = Singleton::Instance();

some_ptr.a = 5;

Alerta(some_ptr.a);

}

Aqui está o código de Myers para C++:

class Singleton
{
private:
    Singleton() {}
    Singleton( const Singleton&);
    Singleton& operator=( Singleton& );
public:
    static Singleton& getInstance() {
        static Singleton  instance;
        return instance;
    }
};

E aqui está o mesmo código transposto para a MQL4++, que é a parte técnica da classe no exemplo:

class Symbol_Properties {
private:
   // Реализация технической части singleton'а
  /******************************************************************************/
public: // Вечно в этом MQL4++ что-то не работает: 'Symbol_Properties::Symbol_Prope…' - cannot call private member function
  Symbol_Properties() {};
private: // Восстанавливаем private
  Symbol_Properties(const Symbol_Properties &p);
  void operator =(const Symbol_Properties &);

public:
  static Symbol_Properties *singleton() {
    static Symbol_Properties sp;
    return GetPointer(sp);
  }

Onde está a "feitiçaria" aqui?

Seu exemplo explora erros do compilador MQL4++, em particular, o uso do tipo SomeClass em OnStart() é inadequado, porque este é um tipo aninhado da classe Singleton, e o compilador "adulto" detecta instantaneamente um erro:

try.cpp:33:9: error: unknown type name 'SomeClass'
        SomeClass* some_ptr = Singleton::Instance();
        ^

Entretanto, este não é um ponto crucial, pois um tipo aninhado pode ser especificado corretamente. O que é mais importante é que o tipo SomeClass é declarado na seção privada da classe Singleton e, portanto, o uso de SomeClass em OnStart() está agora fundamentalmente errado, o que o compilador "adulto" relata imediatamente:

try.cpp:33:20: error: 'SomeClass' is a private member of 'Singleton'
        Singleton::SomeClass* some_ptr = Singleton::Instance();
                   ^

Sua implementação funcionará, a menos que o compilador MQL4++ conserte a bacanalia de controle de acesso.

 

1. Maerse, não Maerse, que porra importa se o código funciona e faz a coisa certa sem erros em MQL e não em ++.

2. O seu código faz o que deve fazer? Não, não tem. Você já entendeu tudo.

Meu exemplo mostra o tratamento de erros (com respeito ao C++) na MQL. Se algo não for conveniente, veja os pontos 1 e 2.

4. Quanto à criação de um ponteiro para uma classe privada, sim, é um erro de MQL, mas não há um auto para identificar o tipo, por isso é bom que funcione. \

(p.s. Eu posso ter exagerado às custas do automóvel, eu deveria verificar)

5. Não encontrei nenhuma maneira na MQL de desreferenciar um ponteiro para obter um objeto, portanto considero supérfluo o construtor de cópias privadas e o operador de cessão.

Tente usá-los, eu ficarei feliz em ver o caminho))

 
ALXIMIKS:

1. Maerse, não Maerse, que porra importa se o código funciona e faz a coisa certa sem erros em MQL, não em ++.

2. O seu código faz o que deve fazer? Não, não tem. Você já entendeu tudo.

Meu exemplo mostra o tratamento de erros (com respeito ao C++) na MQL. Se algo não for conveniente, veja os pontos 1 e 2.

4. Quanto à criação de um ponteiro para uma classe privada, sim, é um erro de MQL, mas não há um auto para identificar o tipo, por isso é bom que funcione. \

(p.s. talvez eu tenha ido longe demais às custas do automóvel, eu deveria verificar isso)

5. Não encontrei nenhuma maneira na MQL de desreferenciar um ponteiro para obter um objeto, portanto considero supérfluo o construtor de cópias privadas e o operador de cessão.

Tente usá-los, eu ficarei feliz em ver o caminho))

1. Agora - faz, mas NÃO o caminho (explicação abaixo).

2. Se eles não consertarem - isso também não vai servir. E é pouco provável que possa ser implementado.

3. não é uma forma de contornar os insetos, é a exploração.

4. Há muita coisa que não está lá.

5. Tais coisas podem ser possíveis nesta versão, em particular, acho que flashei que o copiador não é sintetizado, mas isso não garante que ele não começará a sintetizar em versões futuras. A sobrecarga de declará-los, por outro lado, eu acho que é insignificante.

Agora para explicar por que seu código não só tem os problemas potenciais que mencionei no post anterior, mas também por que ele não é, em princípio, um singleton e não será, e se eles consertam a bacanalia de acesso ou não:

#property strict

class Singleton{
private:
         class SomeClass{
         public:
            int a;
         };
        Singleton(){}
        ~Singleton(){}   
public:
        static SomeClass* Instance(){
                        static SomeClass a;
                        return GetPointer (a);
                }
        };
        int i;

void OnStart()
{       
        SomeClass* some_ptr = Singleton::Instance();
        SomeClass obj1;
        SomeClass obj2;

        obj1.a = 3;
        obj2.a = 7;

        some_ptr.a = 5;
        Print("some_ptr.a = ", some_ptr.a);          
        Print("obj1.a = ", obj1.a);          
        Print("obj2.a = ", obj2.a);          
}

Este código é executado com bastante sucesso:

10:09:27 Script 3 EURUSDm,H1: loaded successfully
10:09:27 3 EURUSDm,H1: initialized
10:09:27 3 EURUSDm,H1: some_ptr.a = 5
10:09:27 3 EURUSDm,H1: obj1.a = 3
10:09:27 3 EURUSDm,H1: obj2.a = 7
10:09:27 3 EURUSDm,H1: uninit reason 0
10:09:27 Script 3 EURUSDm,H1: removed

Você vê quantos singleton's conseguiram ser criados, enquanto ONCE existem?

Algo neste sentido mudaria para seu código se o bacanal de acesso fosse consertado?

Será que isso vai mudar no meu código?

Você acha que, quanto mais desiludido você fizer sua afirmação, mais correta ela será?

 

Sim, obrigado por sua atenção, você está certo, também não é um único botão nesta variante.

Com relação aos construtores e operadores implícitos - torná-los explícitos e tentar usá-los, me parece que não funcionarão por causa da impossibilidade de desreferenciar o ponteiro para o objeto

Por que não funciona, 'ptr' - não pode chamar a função de membro protegido :

class smart_ptr{
            Singleton* ptr;
      public:        
            smart_ptr(Singleton* val): ptr(val){}          
            smart_ptr(): ptr(NULL){} 
            ~smart_ptr(){delete ptr;}
      };
 
ALXIMIKS:

Sim, obrigado por sua atenção, você está certo, também não é um único botão nesta variante.

Com relação aos construtores e operadores implícitos - torná-los explícitos e tentar usá-los, me parece que não funcionarão por causa da impossibilidade de desreferenciar o ponteiro para o objeto

Por que não funciona, 'ptr' - não pode chamar a função de membro protegido :

Não parece funcionar e há muito mais bugs aqui. É uma pena que muito poucas pessoas percebam isso. Não quero entrar em uma discussão, mas na verdade há uma enorme diferença. Algumas coisas que se aplicam a estruturas em C++ não funcionam em MKL4. Mas eu vou ficar em silêncio... senão eles começarão a fazer perguntas como:

"Por que eu preciso disso".

Se pelo menos para que eu não pudesse entrar em um livro didático inacabado, mas simplesmente escrever coisas que funcionam em C++ em MKL4 e não pensar se elas funcionam aqui ou não. Não preciso de mais nada nesta fase...