Download MetaTrader 5

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

To add comments, please log in or register
Max Payne
411
Max Payne  

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!

Rashid Umarov
Admin
12400
Rashid Umarov  
We are going to implement forward declaration. Please wait a bit.

Max Payne
411
Max Payne  
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!


Bogdan Caramalac
1112
Bogdan Caramalac  
Are we gonna have dynamic structures too ? (like the ones used in C++ to implement trees?)
Rashid Umarov
Admin
12400
Rashid Umarov  
TheEconomist:
Are we gonna have dynamic structures too ? (like the ones used in C++ to implement trees?)
What about CTree ?
Bogdan Caramalac
1112
Bogdan Caramalac  
Cool!
Rashid Umarov
Admin
12400
Rashid Umarov  
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\

EggShen
25
EggShen  

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;
  }
}
Rashid Umarov
Admin
12400
Rashid Umarov  
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

EggShen
25
EggShen  
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... 

EggShen
25
EggShen  

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?

12
To add comments, please log in or register