Class constructor overload problem SOLVED

 

Hi.

I am working on wrapping Global Variables of Terminal in a class so I can use them like a simple variables array, just in abstract data type CGlobalObject. However... I don't get why the compiler doesn't seem to like me making different overloads of the class constructor method. I must be overlooking something, but it is like in a game of chess: The less pieces are left, the more difficult it seems not to overlook anything. Don't quote me on this one.

#include <Object.mqh>
class CGlobalObject : public CObject
  {
private:
   int               m_index;

protected:
                     CGlobalObject(void);
                     CGlobalObject(const double a_value);
                    ~CGlobalObject(void);

   int               GlobalIndex(void) {return(m_index);}
   string            GlobalName() {return(GlobalVariableName(m_index));}
   double            GlobalGet(void) {return(GlobalVariableGet(GlobalName()));}
   datetime          GlobalSet(double a_value) {return(GlobalVariableSet(GlobalName(),a_value));}
   bool              GlobalCheck(void) {return(GlobalVariableCheck(GlobalName()));}
   bool              GlobalDelete() {return(GlobalVariableDel(GlobalName()));}
   
   
   string            ConcName(void);

  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CGlobalObject::CGlobalObject(void) :
   m_index(GlobalVariablesTotal())
  {
   GlobalVariableSet(ConcName(),0.0); 
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CGlobalObject::CGlobalObject(int a_value) :
   m_index(GlobalVariablesTotal())
  {
   GlobalVariableSet(ConcName(),a_value); 
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string            CGlobalObject::ConcName()
  {
   string   sep = "|#|";
   int      count = 0;
   string   prog_type = (string)(ENUM_PROGRAM_TYPE)MQLInfoInteger(MQL_PROGRAM_TYPE);
   string   prog_name = MQLInfoString(MQL_PROGRAM_NAME);
   string   obj_type = "Opportunity";
   string   conc_name = prog_type + sep + prog_name + sep + obj_type + sep + _Symbol + sep + (string)_Period;
   int      glob_total = GlobalVariablesTotal();
   while(count < 1000 && !IsStopped() && GlobalVariableCheck(conc_name))
     {
      PrintFormat("%s %s already exists on the chart!", prog_type, conc_name);
      count++;
      conc_name += sep + (string)count;
     }
   GlobalVariableSet(conc_name, 0.0);
   return(conc_name);
  }

//+------------------------------------------------------------------+


So. Compiler says: CGlobalObject - member function already defined with different parameters - How is it different from this below?

//+------------------------------------------------------------------+
//| Matrix (int)                                                     |
//+------------------------------------------------------------------+
class CMatrixInt
  {
private:
   //--- array
   CRowInt           m_rows[];
public:
   //--- constructors, destructor
                     CMatrixInt(void);
                     CMatrixInt(const int rows);
                     CMatrixInt(const int rows,const int cols);
                    ~CMatrixInt(void);
   //--- methods
   int               Size(void) const;
   void              Resize(const int n,const int m);
   //--- overloading
   CRowInt          *operator[](const int i) const;
   void              operator=(const CMatrixInt &m);
  };
//+------------------------------------------------------------------+
//| Constructor without parameters                                   |
//+------------------------------------------------------------------+
CMatrixInt::CMatrixInt(void)
  {

  }
//+------------------------------------------------------------------+
//| Constructor with one parameter                                   |
//+------------------------------------------------------------------+
CMatrixInt::CMatrixInt(const int rows)
  {
   ArrayResizeAL(m_rows,rows);
  }
//+------------------------------------------------------------------+
//| Constructor with two parameters                                  |
//+------------------------------------------------------------------+
CMatrixInt::CMatrixInt(const int rows,const int cols)
  {
   ArrayResizeAL(m_rows,rows);
   for(int i=0;i<rows;i++)
      m_rows[i].Resize(cols);
  }

I know it won't compile. It is from Include/Math/matrix if you need the source.

Documentation on MQL5: Language Basics / Object-Oriented Programming / Static Members of a Class
Documentation on MQL5: Language Basics / Object-Oriented Programming / Static Members of a Class
  • www.mql5.com
Static Members of a Class - Object-Oriented Programming - Language Basics - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

Can't you make the parameters of the constructor even more simple (untested - just an idea):

#include <Object.mqh>
class CGlobalObject : public CObject
  {
private:
   int               m_index;

protected:
                     CGlobalObject(const double a_value=DBL_MAX);

...

CGlobalObject::CGlobalObject(int a_value)
  {
   m_index = GlobalVariablesTotal();
   if ( a_value==DBL_MAX ) {...}
   else {... }
  }

This way you can call the constructor - I think - either with or without a value and as it called only once for an object it wont crash the performance.

But why do you write  : m_index(GlobalVariablesTotal()) ??

m_index is int not a function!

 
Carl Schreiber #:

Can't you make the parameters of the constructor even more simple (untested - just an idea):

This way you can call the constructor - I think - either with or without a value and as it called only once for an object it wont crash the performance.

But why do you write  : m_index(GlobalVariablesTotal()) ??

m_index is int not a function!

It is because I wanted to experiment with the OOP syntax and I saw this somewhere in standard library, I think it is called direct initialisation, but I haven't come to testing it yet.

When you think about the indizes of global variables, they are unique. Just realized I will have to build some logic for when they get deleted after a month.

I figured if I wanted to get the GlobalVariableName(int index) I would need the actual index of the global variables, then I can use GlobalVariableName(m_index) to call all the other functions...


Thanks for the contribution. Will give it a thought, although it would be nice to be able to use what I can learn from standard library. On second thought I will probably wind up using it, thanks!

 
Tobias Johannes Zimmer #:

It is because I wanted to experiment with the OOP syntax and I saw this somewhere in standard library, I think it is called direct initialisation, but I haven't come to testing it yet.

When you think about the indizes of global variables, they are unique. Just realized I will have to build some logic for when they get deleted after a month.

I figured if I wanted to get the GlobalVariableName(int index) I would need the actual index of the global variables, then I can use GlobalVariableName(m_index) to call all the other functions...


Thanks for the contribution. Will give it a thought, although it would be nice to be able to use what I can learn from standard library. On second thought I will probably wind up using it, thanks!

To save information constantly and available for other terminals I would use csv files in the Common folder.

It is so easy to read such a file into an array of all lines and then split a line into cells:

// read a csv file in an array of lines
int getCsvLines( const string fName, string &l[], int flag=0, ushort sepLine='\n') { // alternative to FileOpen 
   uchar Bytes[]; 
   return( FileLoad(fName, Bytes, flag) ? StringSplit(CharArrayToString(Bytes), sepLine, l) : 0);
}
// and split each line into an array of cells:
int getAllCells(const string line, string &cells[], ushort sepItm=';'){
   int nI = StringSplit(line,sepItm,cells); // ushort SepItem = StringGetCharacter(";",0);
   return(nI);
}
 

So somebody pm'd me and they said it should be like this:

CGlobalObject::CGlobalObject(double a_value) :
   m_index(GlobalVariablesTotal())
  {
   GlobalVariableSet(ConcName(),a_value); 
  }

That is what I overlooked. Then again the error message didn't make very much sense in that respect.

 
Carl Schreiber #:

To save information constantly and available for other terminals I would use csv files in the Common folder.

It is so easy to read such a file into an array of all lines and then split a line into cells:

Oh, I have my problems with files. Tried to work through some article but the Scripts didn't do what the article said, it was pretty frustrating to the point where I asked myself if there could be something wrong with my file system. But this is a topic for another time.