MQL5: How to define mutually dependent classes? (forward declaration is not supported!)

 

Hi,

I'm baffled.

If "forward declaration" of classes is not allowed (as it is in MQL5),
what is the preferred method of implementing two mutually dependent classes?

I have two classes, say Worker and Manager.
They have to maintain a reference (pointer) to each other, the Worker needs to know his Manager
and the Manager needs to know his (list of) Workers.

The preferred C++ solution to this problem, is to introduce a "forward declaration" of the class to be referenced like:

class Manager; //forward declaration

class Worker {

    protected:
        Manager *_manager;
    ...
}

What is the MQL5 solution to this issue?

Thanks in advance!

 
We are going to implement forward declaration. Please wait a bit.

 
Rosh:
We are going to implement forward declaration. Please wait a bit.

Hi Rosh,

thanks for your rapid reply!

Aahh, that's good news!
Will this be in time for ATC 2010?
(I'm afraid probably not, so I think I'll have to hack a workaround this time)

Cheers!


 
Are we gonna have dynamic structures too ? (like the ones used in C++ to implement trees?)
 
TheEconomist:
Are we gonna have dynamic structures too ? (like the ones used in C++ to implement trees?)
What about CTree ?
 
Cool!
 
TheEconomist:
Cool!

FYI


Standard Library

This group of chapters contains the technical details of the MQL5 Standard Library  and descriptions of all its key components.

MQL5 Standard Library is written in MQL5 and is designed to facilitate writing programs (indicators, scripts, experts) to end users. Library provides convenient access to most of the internal functions MQL5.

MQL5 Standard Library is placed in the working directory of the terminal in the 'Include' folder.

Section

Location

Base class

Include\

Classes of data

Include\Arrays\

Classes for file operations

Include\Files\

Classes for string operations

Include\Strings\

Classes for graphic objects

Include\Objects\

Class for working with chart

Include\Charts\

Technical indicators

Include\Indicators\

Trade Classes

Include\Trade\

 

So for the original post's situation:

class Manager; //forward declaration

class Worker {

    protected:
        Manager *_manager;
    ...
}

What is the best way to work around this? I am having a similar issue. I have a class instantiated in the root class that stores pointers to a few global variable and CObjects, which I pass as a pointer to into each classes constructor. Compiling fails...

 

 

(abridged...)

class main
{
  GlobalVars* _globalVars

  SomeOtherClass*  _someOtherClass = new SomeOtherClass(_globalVars);
  _globalVars.setSomeOtherClass(SomeOtherClass);
}


class SomeOtherClass
{
  GlobalVars* _globalVars

  SomeOtherClass(GlobalVars* gv)
  {
    _globalVars = gv
  }
}


class GlobalVars
{
  SomeOtherClass* _someOtherClass

  setSomeOtherClass(SomeOtherClass* aClass)
  {
    _someOtherClass = aClass;
  }
}
 
EggShen:

So for the original post's situation:

What is the best way to work around this? I am having a similar issue. I have a class instantiated in the root class that stores pointers to a few global variable and CObjects, which I pass as a pointer to into each classes constructor. Compiling fails...

Try something like this

class GlobalVars;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class SomeOtherClass
  {
   GlobalVars       *_globalVars;
public:
                     SomeOtherClass(GlobalVars *gv){_globalVars=gv;}
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class GlobalVars
  {
   SomeOtherClass   *_someOtherClass;
public:
   void setSomeOtherClass(SomeOtherClass *aClass) {_someOtherClass=aClass;}
  };
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class main
  {
  public:
   GlobalVars       *_globalVars;
   SomeOtherClass *_someOtherClass;

   main() 
   {
   _globalVars=new GlobalVars;
   _globalVars.setSomeOtherClass(_someOtherClass);
   _someOtherClass=new SomeOtherClass(_globalVars);
    }

  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   
  }
//+------------------------------------------------------------------+

But you should remember you will catch a critical error.

See also The Order of Object Creation and Destruction in MQL5 and Using the Object Pointers in MQL5

 
Rosh:

Try something like this

But you should remember you will catch a critical error.

See also The Order of Object Creation and Destruction in MQL5 and Using the Object Pointers in MQL5

I have separate class files for each class. I can't #include the GlobalVars class into SomeOtherClass because it throws a trillion compile errors. I noticed that you declared AND implemented all classes in one file (including the GlobalVars class). Is this the only way? Otherwise #include does not allow compiling.

 

Thanks for the help... 

 

Update:

In the SomeOtherClass file I declared GlobalVars class at the top, then put #include "GlobalVars.mqh" at the bottom of the file. Everything seems to work now. I didn't think to rearrange my #include's. What is the best practice for including other classes? Is it best to declare the importing class at the top and then add the #includes at the bottom?

Reason: