Download MetaTrader 5

OOP, creating an instance from within the contructor of another class - how?

To add comments, please log in or register
Carl Schreiber
7364
Carl Schreiber  
Hi,

in the class CI the constructor needs to create an instance of another class (CQ) which is forward declared - but this fails :(

The mt4 compiler complains:

'CQ' - struct undefined CI.mqh  105     25
 '=' - type mismatch    CI.mqh  105     19

Cry - why?

class CQ;  // forward declaration
class CI : public CObject {
   public:
      CI::CI(CQ* &q[], const int i); // contructor
...

} 

CI::CI(CQ* &q[], const int i) {  //  constructor
   ...
   int n = ArraySize(q);  // start to create another (new) instance of CQ
   ArrayResize(q,n+1);    // one more
   q[n] = new CQ(i);      // <= 'CQ' - struct undefined CI.mqh  ERROR??
}

The constructor of CQ exists with exactly this parameter (in case the compiler checks the existence of CQ...), but anyway the class CQ is declared (forward) in IC - what do I wrong??

Thanks!

Stanislav Korotky
22141
Stanislav Korotky  
Carl Schreiber:

Please, provide more code. You have some errors in omitted part. This compiles:

class CQ;  // forward declaration

class CI //: public CObject
{
   public:
      CI(CQ* &q[], const int id); // contructor

}; 

class CQ
{
  public:
    CQ(int i){};
};

CI::CI(CQ* &q[], const int id)
{
  int i = 0;
  int n = ArraySize(q);  // start to create another (new) instance of CQ
  ArrayResize(q,n+1);    // one more
  q[n] = new CQ(i);      // NO ERROR HERE
}
Carl Schreiber
7364
Carl Schreiber  
Stanislav Korotky:

Please, provide more code. You have some errors in omitted part. This compiles:

May be it does not compiler here with me because CQ is one file and CI the other file?

// file CI.mqh

class CQ;  // forward declaration
class CI //: public CObject
{
   public:
      CI(CQ* &q[], const int id); // contructor
}; 

CI::CI(CQ* &q[], const int id)
{
  int i = 0;
  int n = ArraySize(q);  // start to create another (new) instance of CQ
  ArrayResize(q,n+1);    // one more
  q[n] = new CQ(i);      // and now??
}
This part was from the other file it is not part of the file for the class CI!!
//file CQ.mqh
class CQ
{
  public:
    CQ(int i){};
};
Stanislav Korotky
22141
Stanislav Korotky  
Carl Schreiber:

May be it does not compiler here with me because CQ is one file and CI the other file?

This part was from the other file it is not part of the file for the class CI!!
Where do you include both headers?
Carl Schreiber
7364
Carl Schreiber  

Anyway try this - it's the complete file:

//+------------------------------------------------------------------+
//|                                                           CI.mqh |
//|                                                             Test |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Test"
#property link      "http://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CQ;
class CI
  {
private:

public:
                     CI(CQ* &q[], const int id); // contructor
                    ~CI();
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CI::CI(CQ* &q[], const int id)
{
  int n = ArraySize(q);  // start to create another (new) instance of CQ
  ArrayResize(q,n+1);    // one more
  q[n] = new CQ(id);      // and now??
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CI::~CI()
  {
  }
//+------------------------------------------------------------------+
Stanislav Korotky
22141
Stanislav Korotky  
Carl Schreiber:

Anyway try this - it's the complete file:

And where is CQ definition? Where is include?
Carl Schreiber
7364
Carl Schreiber  

I can't include it as CQ has as well a forward declaration to CI.

As it is not possible for both files to include each other I have to use the forward declaration.

Stanislav Korotky
22141
Stanislav Korotky  
Carl Schreiber:

I can't include it as CQ has as well a forward declaration to CI.

As it is not possible for both files to include each other I have to use the forward declaration.

It makes no sense. Forward declaration is intended to break such loops in dependencies. But you need an include anyway. Forward declaration DOES NOT define a class, but tells compiler that you'll include the definition lately.
Stanislav Korotky
22141
Stanislav Korotky  
class CQ;  // forward declaration

class CI
{
   public:
      CI(CQ* &q[], const int id); // contructor

}; 

class CQ
{
  private:
    const CI *owner;
    
  public:
    CQ(const CI *o)
    {
      owner = o;
    };
};

CI::CI(CQ* &q[], const int id)
{
  int n = ArraySize(q);  // start to create another (new) instance of CQ
  ArrayResize(q,n+1);    // one more
  q[n] = new CQ(&this);
}
Both classes have references to each other. No problem.
Carl Schreiber
7364
Carl Schreiber  

ok - thanks!

But I thought it would be a nice feature of OOP to have each class with its library of methods in its own file.

Ex Ovo Omnia
3358
Ex Ovo Omnia  
Carl Schreiber:

ok - thanks!

But I thought it would be a nice feature of OOP to have each class with its library of methods in its own file.

Sure, it is quite common, in fact Java has it as the mandatory rule for public classes. Though the circular dependencies in your example are not a good example of a public class.

12
To add comments, please log in or register