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

 
Ovo Cz:

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.

1) Well my two classes depend on each other and

2) real problems differ unfortunately from these wonderful and brilliant examples in the explanatory documentations.

 
Carl Schreiber:

1) Well my two classes depend on each other and

2) real problems differ unfortunately from these wonderful and brilliant examples in the explanatory documentations.

You can revise your class hierarchy. Exact methods depends on what you want to achieve.
 

Well it's pretty easy what I want: At initialisation Class 1 CI 'acts' on Class 2 CQ but in OnStart() Class 2 CQ 'acts' on Class 1 CI.

This is the relation: For each CI exists for sure one CQ, but CQ can has 1 or more CI.

Therefore:

  1. CI needs a reference to 'its' CQ, (check and construct at OnInit)
  2. CQ an array of references to CI, (call CQ, CQ calls CI)
  3. and 'I' need arrays of both. (start CQ and request values from CI)
 
Well, I must say that class name CQ and CI tell nothing, so understanding of their purposes and relations is very hard. I don't ask you to disclose an algorithm but there should be available something (meaning, responsibility, etc) to get the whole picture. This is important to find proper class design for your case. Currently you only tells us how you see your classes should be, but you can't get them as you see it. This is a deadend.
 

Also please provide more info about exact errors you get. I compile your multiple files without an issue.

// file CI.mq4
#include <CI.mqh>

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);      // works
}
// CI.mqh
#include <CQ.mqh>

#ifndef _CI_
#define _CI_

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

#endif
// file CQ.mqh
#ifndef _CQ_
#define _CQ_

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

#endif
 

Attached are four files. The file with the base class(es) CI and CQ:  TestCQI.mqh  This file compiles correctly!

class CQ;  // forward declaration
class CI   //: public CObject
{
   private: 
      int m_id;
   protected:
      CI(CQ* &q[], const int id); // constructor
   public:
      virtual int calc() { return(-1); }
}; 

//file CQ.mqh
class CQ
{
  public:
    CQ(int id){};
};

//#####   library of methods for both    ######//
// ....
CI::CI(CQ* &q[], const int id)
{
  m_id = 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??
}

Now I want to create a couple of derived classes of CI TestDerv1CI, TestDerv2CI, TestDerv3CI, TestDerv4CI, but I would like be able to to store their individual reference in one array of references:

   CI* ref[2]; // correct? not tested yet.
   ref[0] = new TestDerv1CI();
   ref[1] = new TestDerv2CI();

This is the way I finally would like to able to handle them. Alternatively but not that convenient I can do as well:

   TestDerv1CI* ref1 = new TestDerv1CI();
   TestDerv2CI* ref2 = new TestDerv2CI();

For both ways I think I would need a constructor for the derived classes - and that causes the compiler to complain. I tried to use the GekkoEA example:

class Order {
  protected:      
   int      m_TicketNumber;
   int      m_MagicNumber;
      
   Order( int magicnumber ){
      m_MagicNumber = magicnumber;
      m_TicketNumber = -1;
   }
...
}
...
class LongOrder : public Order {
  public:
   LongOrder( int magicNumber ) : Order( magicNumber ){ }
}

I tried to copy that in my derived class:

#include <TestCQI.mqh>
class TestDerv1CI : public CI
  {
private:
         int m_id;
public:
         TestDerv1CI(CQ* &q[], const int id) : CI(CQ* &q[], const int id) {}; // contructor  line 19 <= ERROR
         int calc(void);
};
int TestDerv1CI::calc(void) {
   return( 2+4 );
}

And this makes my compiler cry:

'TestDerv1CI.mqh'       TestDerv1CI.mqh 1       1
'TestCQI.mqh'   TestCQI.mqh     1       1
'&' - unexpected token  TestDerv1CI.mqh 19      55
']' - expression expected       TestDerv1CI.mqh 19      58
'&' - illegal operation use     TestDerv1CI.mqh 19      55
'id' - unexpected token TestDerv1CI.mqh 19      71
')' - unexpected token  TestDerv1CI.mqh 19      73
'&' - parameter passed as reference, variable expected  TestDerv1CI.mqh 19      55

Ok, this seems to to work, now I am trying to use the shape example from the editor's reference (search for Virtual Functions):

#include <TestCQI.mqh>
class TestDerv2CI : public CI  { // <= line 14
private:

public:
         int calc(void);
};
  
int TestDerv2CI::calc(void) {
   return( 3+9 );
}

Wow, this compiles correctly !!!

Now I write a little script - and am stuck again, compiler errors :(

#include <TestDerv2CI.mqh>
void OnStart()
  {
//---
   
  }
//+------------------------------------------------------------------+
/* compiler error:
'TestOOP.mq4'   TestOOP.mq4     1       1
'TestDerv2CI.mqh'       TestDerv2CI.mqh 1       1
'TestCQI.mqh'   TestCQI.mqh     1       1
'CI' - wrong parameters count   TestDerv2CI.mqh 14      7
*/

What do I have to do that I can write in my script:

#include <TestDerv1CI.mqh>
#include <TestDerv2CI.mqh>
void OnStart()  {
  CQ* q[];
  CI* rCI[2];
  rCI[0] = new TestDerv1CI(q,1);
  rCI[1] = new TestDerv2CI(q,2);
}
/* compiler messages:
'TestCQI.mqh'   TestCQI.mqh     1       1
'TestDerv2CI.mqh'       TestDerv2CI.mqh 1       1
'TestDerv2CI' - wrong parameters count  TestOOP.mq4     21      16
'&' - unexpected token  TestDerv1CI.mqh 19      55
']' - expression expected       TestDerv1CI.mqh 19      58
'&' - illegal operation use     TestDerv1CI.mqh 19      55
'id' - unexpected token TestDerv1CI.mqh 19      71
')' - unexpected token  TestDerv1CI.mqh 19      73
'&' - parameter passed as reference, variable expected  TestDerv1CI.mqh 19      55
7 error(s), 0 warning(s)                8       1
*/

Thanks for your patience and effort!!

Calli








Files:
 

Here is a couple of your fixed files.

Yet it's still not clear what you want to achieve. This is very very strange to pass a reference of an external array to another constructor in order to create other class instance and add into this array, which is not related to the class which object is being constructed.

Files:
 

Tank you very much!

Sorry for bothering I haven't been precise enough :(

Reason: