Download MetaTrader 5

How can I create a singleton class in mql4

To add comments, please log in or register
What are the latest MQL5.community news? The Wall section will tell you!
M1cha31
18
M1cha31 2016.10.21 10:43 

Hi all,

I wanted to create a singleton (OO design pattern) class and wrote the following code. However, I'm getting an unresolved static variable pool error while compiling. Any suggestions how to fix it?

class Pool {
   private:
      static Pool* pool;
      Pool (void) {
      }
   
   public:     
      static Pool* getInstance() {
         if (!pool){
            pool = new Pool();
         }          
         return(pool);
      }      
};
Ex Ovo Omnia
3151
Ex Ovo Omnia 2016.10.21 10:55  
JC
1456
JC 2016.10.21 11:56  

That documentation isn't exactly super-clear about the fact that, like in C++, the static variable must be initialized:

class Pool {
   private:
      static Pool* instance;
      Pool() {}

   public:
      static Pool * getInstance() {
         if (!instance) instance = new Pool();
         return instance;
      }   
};
Pool * Pool::instance = NULL;

 The further problem is that MT4/MQL4 then gives a helpful runtime warning, upon termination, about the fact that the instance of the class hasn't been explicitly deleted.

 The following version is simpler, but suffers from the same issue that there's no way of cleaning up the object reference, and therefore MT4/MQL4 complains:

class Pool {
   private:
       Pool() {}
       
   public:     
      static Pool * getInstance() {
         static Pool * instance = new Pool();
         return instance;
      }
};
M1cha31
18
M1cha31 2016.10.21 12:06  
jjc:

That documentation isn't exactly super-clear about the fact that, like in C++, the static variable must be initialized:

 The further problem is that MT4/MQL4 then gives a helpful runtime warning, upon termination, about the fact that the instance of the class hasn't been explicitly deleted.

 The following version is simpler, but suffers from the same issue that there's no way of cleaning up the object reference, and therefore MT4/MQL4 complains:

 

Thank you!
JC
1456
JC 2016.10.21 12:08  
jjc:

The further problem is that MT4/MQL4 then gives a helpful runtime warning, upon termination, about the fact that the instance of the class hasn't been explicitly deleted. 

I can't see an alternative to doing the following:

class Pool {
   private:
      static Pool* instance;
      Pool() {}

   public:
      static Pool * getInstance() {
         if (!instance) instance = new Pool();
         return instance;
      }   
      static void Release() {
         delete instance;
         instance = NULL;
      }
};
Pool * Pool::instance = NULL;

...

void OnDeinit(const int reason)
{
    Pool::Release();
}
... at which point, unless you are part of the 0.001% of MQL4 developers working as part of a team and sharing code on a large project, it becomes increasingly less clear what you have achieved compared to simply having a single instance of a class in a global variable.
JC
1456
JC 2016.10.21 14:13  
jjc:

... at which point [...]

If we want to get cute, then we can template it as follows:

#define SINGLETON(T) class T : public Singleton<T>  { private: T() {SingleInstanceConstructor();}  public: static T * getInstance() {if (!instance) instance = new T();return (T*)instance;}
template <typename T>
class Singleton {
   private:
      virtual void SingleInstanceConstructor() = NULL;

   protected:
      static T * instance;
      Singleton() {}
      
   public:
      static void Release() {
         if (instance) {
            delete instance;
            instance = NULL;
         }
      }
};
template <typename T>
T * Singleton::instance = NULL;

 

Any individual singleton class can then be declared more succinctly as follows:

SINGLETON(Pool)
private:
   // Takes the place of the normal constructor; must be declared
   void SingleInstanceConstructor() { ... etc ...}

public:
   // Whatever public functions you need in this singleton...
};


Still need to clean up any singletons which are used, in OnDeinit. 

To add comments, please log in or register