Overloaded = operator in CList subclass. Not getting Total() result

 

Hello there,

Thanks to @nicholishen, I created the following class:-

//+------------------------------------------------------------------+
//|                                                 gwTrendLines.mqh |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//---
#include <Arrays\List.mqh>
#include <gwTrendLine.mqh>
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CTrendLines : public CList
  {
private:

public:
                     CTrendLines();
                    ~CTrendLines();
                     CTrendLines(const CTrendLines &trendLines); // Copy

   CTrendLines *operator=(const CTrendLines &trendLines)
     {

      return(GetPointer(this));

     }

   void              Add(double price1,datetime time1,double price2,datetime time2);
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CTrendLines::CTrendLines()
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CTrendLines::~CTrendLines()
  {
  }
//+------------------------------------------------------------------+
void CTrendLines::Add(double price1,datetime time1,double price2,datetime time2)
  {

   for(CTrendLine *high=GetFirstNode();high!=NULL;high=high.Next())
     {

      if(high.IsMatch(price1,time1,price2,time2))
        {

         return;

        }

     }

   CList::Add(new CTrendLine(price1,time1,price2,time2));

  }
//+------------------------------------------------------------------+

The class works well in its own right but I added a Getter to another class of which the above is a member. I also had to add the copy ctor and the "=" overload.

Even when I can see that the list is populated with CTrendLine objects, when I try to access CTrendLines through the getter, the Total() method returns 0 (zero). I feel sure I must not have created the copy ctor/overloaded "=" correctly but beyond that, I'm unsure why the underlying list isn't making itself available.

Any ideas/suggestions appreciated.

Cheers!

 
Geester: I also had to add the copy ctor and the "=" overload.

You created a empty ones. They do nothing. They don't even call the superclass ones.

MT4/5 now automatically generates a assignment operator.
          MetaTrader 5 Platform Beta Build 1625 - General - MQL5 programming forum (Item № 8)

 
whroeder1:

You created a empty ones. They do nothing. They don't even call the superclass ones.

MT4/5 now automatically generates a assignment operator.
          MetaTrader 5 Platform Beta Build 1625 - General - MQL5 programming forum (Item № 8)


Hi @whroeder1 - thanks for the link. That's great information to know if you are using MQL5. As I'm using MT4, could you advise what I might need to do, presumably to call the superclass? Sorry to be a pain! I'm new to MT4 and no previous CPP experience so, I'm "flying by the seat of my pants", at the moment :)

Cheers!

--G



 
  1. Why did you post your MT4 question in the Root / MT5 General section instead of the MQL4 section, (bottom of the Root page?)
              General rules and best pratices of the Forum. - General - MQL5 programming forum

  2. My previous post was valid for either.
  3. Delete those two functions until you need them to do something special.
 
whroeder1:
  1. Why did you post your MT4 question in the Root / MT5 General section instead of the MQL4 section, (bottom of the Root page?)
              General rules and best pratices of the Forum. - General - MQL5 programming forum

  2. My previous post was valid for either.
  3. Delete those two functions until you need them to do something special.

Didn't realise I had. Apologies - thought I was in General MT4.

What I need to do is to be able to access the data list from a copy. When I get the copy, the list is empty. Hence my original question.

 
Geester:

Hi @whroeder1 - thanks for the link. That's great information to know if you are using MQL5. As I'm using MT4, could you advise what I might need to do, presumably to call the superclass? Sorry to be a pain! I'm new to MT4 and no previous CPP experience so, I'm "flying by the seat of my pants", at the moment :)

Cheers!

--G




You have to define what you want the overloaded function to do. I would assume that you want to copy the collection from one list to another. In that case you would simply do something like this:

#include <Arrays\List.mqh>

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CTrendLines : public CList
{
private:

public:
   void operator=(CList &obj)
   {
      if(!AssignList(&obj))
         Print("Error: ",GetLastError());
   }
   bool AssignList(CList *other)
   {
      Clear();
      for(CObject *obj=other.GetFirstNode();obj!=NULL;obj=obj.Next())
         Add(obj);
      return CompareList(other);
   } 
};
//+-------------------------------------------------


//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   CTrendLines l1,l2;
   for(int i=0;i<10;i++)
      l1.Add(new CObject);
      
   l2=l1;
   
   Print(l2.Total());
}
 
 
nicholishen:

You have to define what you want the overloaded function to do. I would assume that you want to copy the collection from one list to another. In that case you would simply do something like this:


Hey @nicholishen - thanks for the heads-up :)

I created a sub-class of CList, very similar to the one you showed me based on the OOP approach to drawing lines and so forth, on the chart. This worked absolutely great. No problems whatsoever. However, I wanted to pass this CList subclass into another class (via a setter) and when I tried to assign it, the compiler complained. After Googling, it appeared that my CList subclass wanted a copy ctor and "=" overloaded. 

When I tried to access the list from the copy, it was empty, with Total() reporting 0 (zero) despite there actually being many items in the non-copied list. So, I was actually trying to figure out whether I had to do something in the extra code to make the data items available. To my uneducated take on it, I couldn't see anything else to do but, it doesn't seem to work as there is no data in the copy. In that case, I assumed that I was missing something obvious.

Thoughts?

Cheers.

--G

 
Geester:

Hey @nicholishen - thanks for the heads-up :)

I created a sub-class of CList, very similar to the one you showed me based on the OOP approach to drawing lines and so forth, on the chart. This worked absolutely great. No problems whatsoever. However, I wanted to pass this CList subclass into another class (via a setter) and when I tried to assign it, the compiler complained. After Googling, it appeared that my CList subclass wanted a copy ctor and "=" overloaded. 

When I tried to access the list from the copy, it was empty, with Total() reporting 0 (zero) despite there actually being many items in the non-copied list. So, I was actually trying to figure out whether I had to do something in the extra code to make the data items available. To my uneducated take on it, I couldn't see anything else to do but, it doesn't seem to work as there is no data in the copy. In that case, I assumed that I was missing something obvious.

Thoughts?

Cheers.

--G


You mean like this?

//+------------------------------------------------------------------+
//|                                                          Foo.mq4 |
//|                                      Copyright 2017, nicholishen |
//|                         https://www.forexfactory.com/nicholishen |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, nicholishen"
#property link      "https://www.forexfactory.com/nicholishen"
#property version   "1.00"
#property strict


#include <Arrays\List.mqh>

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CTrendLines : public CList
{
private:

public:
   void operator=(CList &obj)
   {
      if(!AssignList(&obj))
         Print("Error: ",GetLastError());
   }
   bool AssignList(CList *other)
   {
      for(CObject *obj=other.GetFirstNode();obj!=NULL;obj=obj.Next())
         Add(obj);
      return CompareList(other);
   } 
  
};
//+-------------------------------------------------

class MyClass 
{
protected:
   CTrendLines *m_line_list;
public:
   void  SetLineList(CTrendLines *list_in) { m_line_list=list_in; }
   int Total(){ return (m_line_list!=NULL?m_line_list.Total():-1);}
};
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   CTrendLines l1,l2;
   MyClass my_class;
   for(int i=0;i<10;i++)
      l1.Add(new CObject);
      
   l2=l1;
   my_class.SetLineList(&l2);
   Print(my_class.Total());
}
 

BTW, 

You only want to use CList when you have a large collection that requires many random insertions. Otherwise use CArrayObj. In most cases it is faster by a very large factor.

#property copyright "nicholishen"
#property version   "1.00"
#include <Arrays\List.mqh>
#include <Arrays\ArrayObj.mqh>
#define N 10000
class MyInt : public CObject
{
public:
   MyInt(int n):number(n){}
   int number;
   int Compare(const CObject* node,const int mode=0)const override
   {
      MyInt *other = (MyInt*)node;
      if(this.number>other.number)return 1;
      if(this.number<other.number)return -1;
      return 0;
   }
};
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int arr[N]={0};
   srand(GetTickCount());
   for(int i=0;i<N;i++)
      arr[i]=rand()%100000;
   ulong micro = GetMicrosecondCount();
   CList *list = new CList;
   for(int i=0;i<N;i++)
      list.Add(new MyInt(arr[i]));
   list.Sort(0);
   for(MyInt *obj=list.GetFirstNode();obj!=NULL;obj=obj.Next())
      if(obj.number == arr[N-1])
         break;
     
   micro = GetMicrosecondCount()-micro;
   Print("List = ",micro);
   delete list;
   micro = GetMicrosecondCount();
   CArrayObj *array = new CArrayObj;
   for(int i=0;i<N;i++)
      array.Add(new MyInt(arr[i]));
   array.Sort(0);
   MyInt *obj=array.At(0);
   for(int i=0;obj!=NULL;obj=array.At(++i))
      if(obj.number == arr[N-1])
         break;
   micro = GetMicrosecondCount()-micro;
   Print("Array = ",micro);
   delete array;
  }
//+------------------------------------------------------------------+
 
nicholishen:

BTW, 

You only want to use CList when you have a large collection that requires many random insertions. Otherwise use CArrayObj. In most cases it is faster by a very large factor.

Fantastic reply, really helpful and informative as usual. I've learned so much from the code samples you've provided and I'm grateful.

Cheers @nicholishen,

--G



Reason: