MQL5: How to declare a (static) member/class variable?

 

Today I decided to dive into the real object-oriented parts of MQL5 and I am afraid I have immediately run into a problem.
I have not been able to find a way to define a (static) class variable!

Let's consider the following example of a widget factory. The class Widget is used to generate Widget objects, but while doing so, the class needs to keep track of the number of widgets that have been created sofar. This is a very common technique.

Below you'll find my first attempt of a script that creates three widgets and reports on the count of widgets.

//

// WidgetFactory.mq5
//
// MQL5 OOP Test Script
//

// creates widgets and keeps count of them
class Widget {

    protected:
        static int _widgetCnt = 0; // *** The problem is here!!!

    public:
        void Widget();
        int getWidgetCnt();
};

// Constructor
void Widget::Widget() {
    _widgetCnt++;
}

int Widget::getWidgetCnt() {
    return(_widgetCnt);        
}


// starts script execution
void OnStart() {
    Widget widget1;
    printf("widget count: %d", widget1.getWidgetCnt());

    Widget widget2;
    printf("widget count: %d", widget2.getWidgetCnt());

    Widget widget3;
    printf("widget count: %d", widget3.getWidgetCnt());
}

Unfortunately, this is not accepted by the compiler, the error report shows:

'static' - syntax error WidgetFactory.mq5       line 11 column 9
'=' - variable is expected      WidgetFactory.mq5       line 11 column 31

The keyword static is not allowed.

Even if it is not what I want, I'll remove 'static'

    protected:
        int _widgetCnt = 0;

This still leaves us with a error message, because apparently members cannot be initialized in this place. (Why not?)

'=' - variable is expected      WidgetFactory.mq5       line 11 column 24

So let's remove the initialization.

Well, now it compiles and while variables get initialized with 0 anway, we're fine in this example.

widget count: 1
widget count: 1
widget count: 1

However, now every Widget-object has its own counter and that is not what we wanted.

The only way to achieve what I intended to do, is by introducing a variable outside of the class hereby violating several OO criteria, e.g.: encapsulation and inheritance.

The changed script now reads:

//
// WidgetFactory.mq5
//
// MQL5 OOP Test Script
//

// creates widgets and keeps count of them
class Widget {

    public:
        void Widget();
        int getWidgetCnt();
};

static int _widgetCnt = 0;

// Constructor
void Widget::Widget() {
    _widgetCnt++;
}

int Widget::getWidgetCnt() {
    return(_widgetCnt);        
}


// starts script execution
void OnStart() {
    Widget widget1;
    printf("widget count: %d", widget1.getWidgetCnt());

    Widget widget2;
    printf("widget count: %d", widget2.getWidgetCnt());

    Widget widget3;
    printf("widget count: %d", widget3.getWidgetCnt());
}

Now the output is like intended:

widget count: 1
widget count: 2
widget count: 3


My question boils down to the following:
How can I define a class-wide static variable in MQL5?

I really hope I'm missing something here, because otherwise it wouldn't even be possible to implement the "Singleton Pattern" in MQL5.

The example code is attached.

Cheers!

Files:
 

You cannot define class-wide static variable in MQL5. May be in future

Use particular variable defined in the global scope. For example

int _Widget_widgetCnt=0; 

 
stringo:

You cannot define class-wide static variable in MQL5. May be in future

Use particular variable defined in the global scope. For example

int _Widget_widgetCnt=0; 


Dear Stringo,

many thanks for your rapid reply!

Though it's good to read, that you guys are considering this for a future version,
I want to reiterate that this (class-wide static variables) is not some kind of exotic feature request,
but an essential issue for any (mature) object-oriented language.

Cheers!


 

Hello,

Well, unfortunately today I came across the same problem. Seems that this is still an issue. I wanted to implement logging system that I could use across many files and classes in my EA using singleton design pattern from this post -> http://www.infernodevelopment.com/singleton-c but unfortunately when I try to declare a static class variable, I get "syntax error".

Does anyone has any idea for a workaround for this? Maybe something using

CLogMan *CLogMan::getLogMan()
  {
   return(GetPointer(this));
  }

MetaQuotes - what about this issue? When will it be fixed as it is already almost 2 years old?

Singleton C++ | Inferno Development
  • www.infernodevelopment.com
The is a design that creates one single instance of a class that can be used throughout multiple files and large projects. Think of like a global class that can be accessed at any moment and will be created only once, if it hasn't already been initialized. It's a very simple concept, that is used so that you can have access to a set of...
 
Plymo:


My question boils down to the following:
How can I define a class-wide static variable in MQL5?

I really hope I'm missing something here, because otherwise it wouldn't even be possible to implement the "Singleton Pattern" in MQL5.

At the moment static members are not allowed in classes. Sorry. Maybe later.
 
Rosh:
At the moment static members are not allowed in classes. Sorry. Maybe later.

That's a huge pity. This is one of the issues that causes that MQL5 can't be considered a fully OO language.  I hope that it eventually gets introduced, as I had to use extern object pointers in all separate files with source code to create a globally available logger and that is definitely not an elegant and state-of-the-art coding solution.

 
We will add the static members in classes soon. We started work with it, please wait a bit.
 
Rosh:
We will add the static members in classes soon. We started work with it, please wait a bit.
Great news! Waiting for the release then.
 

In simple words, Singleton is a pattern and not a keyword. The Singleton pattern has several advantages over static classes. A singleton allows a class for which there is just one, persistent instance across the lifetime of an application. That means, it created a single instance and that instance (reference to that instance) can be passed as a parameter to other methods, and treated as a normal object. While a static class allows only static methods and and you cannot pass static class as parameter. More about....Singleton Pattern Versus Static Class

Mercal

Reason: