Est-il possible d'implémenter un modèle singleton dans MQL4 ? - page 10

 
ALXIMIKS:

Oui, merci de votre attention, vous avez raison, ce n'est pas un singleton dans cette variante non plus.

À propos des constructeurs et opérateurs implicites - rendez-les explicites et essayez de les utiliser, mais je pense que cela ne fonctionnera pas, car vous ne pouvez pas déréférencer un pointeur vers un objet.

Dans MQL4++, les "pointeurs" semblent être déréférencés implicitement :

#property strict

/******************************************************************************/
class A {
public:
  /******************************************************************************/
  A() {
    Print("class A: Конструктор по умолчанию");
  }

  /******************************************************************************/
  A(const A &a) {
    Print("class A: Конструктор копии");
  }

  /******************************************************************************/
  void operator =(const A &a) {
    Print("class A: Оператор присваивания");
  }
};

/******************************************************************************/
void assign(A &l, A &r) {
  Print("Функция assign()");
  l = r;
}

/******************************************************************************/
void OnStart() {
  Print("OnStart(): Создаём по умолчанию");
  A a;

  Print("OnStart(): Получаем \"адрес\" первого объекта");
  A *p = GetPointer(a);

  Print("OnStart(): Создаём копию, прямо инициализируя предыдущим объектом");
  A b(a);

  Print("OnStart(): Выполняем присваивание, используя предыдущий объект");
  b = a;

  Print("OnStart(): Создаём копию, прямо инициализируя так называемым \"указателем\" на предыдущий объект");
  A c(p);

  Print("OnStart(): Выполняем присваивание, используя так называемый \"указатель\" на предыдущий объект");
  b = p;

  Print("OnStart(): Выполняем присваивание так называемому \"указателю\" значения его же самого");
  p = p;

  // *p = *p; Ошибка: '*' - unexpected token, то есть, присвоить объекту другой объект, если есть "адреса" обоих объектов, не так-то просто...

  Print("OnStart(): Выполняем присваивание объекту по \"адресу\" значения его же самого с помощью вспомогательной функции");
  assign(p, p);
}

Le programme se compile et s'exécute avec succès :

22:23:46 Script 3 EURUSDm,H1: loaded successfully
22:23:46 3 EURUSDm,H1: initialized
22:23:46 3 EURUSDm,H1: OnStart(): Создаём по умолчанию
22:23:46 3 EURUSDm,H1: class A: Конструктор по умолчанию
22:23:46 3 EURUSDm,H1: OnStart(): Получаем "адрес" первого объекта
22:23:46 3 EURUSDm,H1: OnStart(): Создаём копию, прямо инициализируя предыдущим объектом
22:23:46 3 EURUSDm,H1: class A: Конструктор копии
22:23:46 3 EURUSDm,H1: OnStart(): Выполняем присваивание, используя предыдущий объект
22:23:46 3 EURUSDm,H1: class A: Оператор присваивания
22:23:46 3 EURUSDm,H1: OnStart(): Создаём копию, прямо инициализируя так называемым "указателем" на предыдущий объект
22:23:46 3 EURUSDm,H1: class A: Конструктор копии
22:23:46 3 EURUSDm,H1: OnStart(): Выполняем присваивание, используя так называемый "указатель" на предыдущий объект
22:23:46 3 EURUSDm,H1: class A: Оператор присваивания
22:23:46 3 EURUSDm,H1: OnStart(): Выполняем присваивание так называемому "указателю" значения его же самого
22:23:46 3 EURUSDm,H1: OnStart(): Выполняем присваивание объекту по "адресу" значения его же самого с помощью вспомогательной функции
22:23:46 3 EURUSDm,H1: Функция assign()
22:23:46 3 EURUSDm,H1: class A: Оператор присваивания
22:23:46 3 EURUSDm,H1: uninit reason 0
22:23:46 Script 3 EURUSDm,H1: removed

Il semble que le langage n'ait PAS de déréférencement défini, mais qu'une conversion standard de pointeur en référence soit définie, au cours de laquelle un déréférencement implicite se produit. C'est cette particularité que la fonction assign() exploite. Vous ne pouvez pas vous passer d'une fonction, car il semble que les références ne peuvent être spécifiées que dans les paramètres de la fonction...

ALXIMIKS:

Pourquoi cela ne fonctionne-t-il pas, 'ptr' - ne peut pas appeler une fonction membre protégée :

class smart_ptr{
            Singleton* ptr;
      public:        
            smart_ptr(Singleton* val): ptr(val){}          
            smart_ptr(): ptr(NULL){} 
            ~smart_ptr(){delete ptr;}
      };
Si cela pose un problème, c'est évidemment parce que le destructeur de la classe Singleton se trouve dans la section protégée.