# Operation Overloading For ease of code reading and writing, overloading of some operations is allowed. Overloading operator is written using the keyword operator. The following operators can be overloaded: - binary +,-,/,*,%,<<,>>,==,!=,<,>,<=,>=,=,+=,-=,/=,*=,%=,&=,|=,^=,<<=,>>=,&&,||,&,|,^ - unary +,-,++,--,!,~ - assignment operator = - indexing operator [] Operation overloading allows the use of the operating notation (written in the form of simple expressions) for complex objects - structures and classes. Writing expressions using overloaded operations simplifies the view of the source code, because a more complex implementation is hidden. For example, consider complex numbers, which consist of real and imaginary parts. They are widely used in mathematics. The MQL5 language has no data type to represent complex numbers, but it is possible to create a new data type in the form of a [structure or class](/en/docs/basis/types/classes). Declare the complex structure and define four methods that implement four arithmetic operations: ``` //+------------------------------------------------------------------+ //| A structure for operations with complex numbers                  | //+------------------------------------------------------------------+ struct complex   {    double            re; // Real part    double            im; // Imaginary part    //--- Constructors                      complex():re(0.0),im(0.0) {  }                      complex(const double r):re(r),im(0.0) {  }                      complex(const double r,const double i):re(r),im(i) {  }                      complex(const complex &o):re(o.re),im(o.im) { }    //--- Arithmetic operations    complex           Add(const complex &l,const complex &r) const;  // Addition    complex           Sub(const complex &l,const complex &r) const;  // Subtraction    complex           Mul(const complex &l,const complex &r) const;  // Multiplication    complex           Div(const complex &l,const complex &r) const;  // Division   }; ``` Now, in our code we can declare variables representing complex numbers, and work with them. For example: ``` void OnStart()   { //--- Declare and initialize variables of a complex type    complex a(2,4),b(-4,-2);    PrintFormat("a=%.2f+i*%.2f,   b=%.2f+i*%.2f",a.re,a.im,b.re,b.im); //--- Sum up two numbers    complex z;    z=a.Add(a,b);    PrintFormat("a+b=%.2f+i*%.2f",z.re,z.im); //--- Multiply two numbers    z=a.Mul(a,b);    PrintFormat("a*b=%.2f+i*%.2f",z.re,z.im); //--- Divide two numbers    z=a.Div(a,b);    PrintFormat("a/b=%.2f+i*%.2f",z.re,z.im); //---   } ``` But it would be more convenient to use usual operators "+", "-", "*" and "/" for ordinary arithmetic operations with complex numbers. Keyword operator is used for defining a member function that performs type conversion. Unary and binary operations for class object variables can be overloaded as non-static member functions. They implicitly act on the class object. Most binary operations can be overloaded like regular functions that take one or both arguments as a class variable or a pointer to an object of this class. For our type complex, overloading in the declaration will look like this: ```    //--- Operators    complex operator+(const complex &r) const { return(Add(this,r)); }    complex operator-(const complex &r) const { return(Sub(this,r)); }    complex operator*(const complex &r) const { return(Mul(this,r)); }    complex operator/(const complex &r) const { return(Div(this,r)); } ``` The full example of the script: ``` //+------------------------------------------------------------------+ //| Script program start function                                    | //+------------------------------------------------------------------+ void OnStart()   { //--- Declare and initialize variables of type complex    complex a(2,4),b(-4,-2);    PrintFormat("a=%.2f+i*%.2f,   b=%.2f+i*%.2f",a.re,a.im,b.re,b.im);    //a.re=5;    //a.im=1;    //b.re=-1;    //b.im=-5; //--- Sum up two numbers    complex z=a+b;    PrintFormat("a+b=%.2f+i*%.2f",z.re,z.im); //--- Multiply two numbers      z=a*b;    PrintFormat("a*b=%.2f+i*%.2f",z.re,z.im); //--- Divide two numbers    z=a/b;    PrintFormat("a/b=%.2f+i*%.2f",z.re,z.im); //---   } //+------------------------------------------------------------------+ //| A structure for operations with complex numbers                  | //+------------------------------------------------------------------+ struct complex   {    double            re; // Real part    double            im; // Imaginary part    //--- Constructors                      complex():re(0.0),im(0.0) {  }                      complex(const double r):re(r),im(0.0) {  }                      complex(const double r,const double i):re(r),im(i) {  }                      complex(const complex &o):re(o.re),im(o.im) { }    //--- Arithmetic operations    complex           Add(const complex &l,const complex &r) const;  // Addition    complex           Sub(const complex &l,const complex &r) const;  // Subtraction    complex           Mul(const complex &l,const complex &r) const;  // Multiplication    complex           Div(const complex &l,const complex &r) const;  // Division    //--- Binary operators    complex operator+(const complex &r) const { return(Add(this,r)); }    complex operator-(const complex &r) const { return(Sub(this,r)); }    complex operator*(const complex &r) const { return(Mul(this,r)); }    complex operator/(const complex &r) const { return(Div(this,r)); }   }; //+------------------------------------------------------------------+ //| Addition                                                         | //+------------------------------------------------------------------+ complex complex::Add(const complex &l,const complex &r) const   {    complex res; //---    res.re=l.re+r.re;    res.im=l.im+r.im; //--- Result    return res;   } //+------------------------------------------------------------------+ //| Subtraction                                                      | //+------------------------------------------------------------------+ complex complex::Sub(const complex &l,const complex &r) const   {    complex res; //---    res.re=l.re-r.re;    res.im=l.im-r.im; //--- Result    return res;   } //+------------------------------------------------------------------+ //| Multiplication                                                   | //+------------------------------------------------------------------+ complex complex::Mul(const complex &l,const complex &r) const   {    complex res; //---    res.re=l.re*r.re-l.im*r.im;    res.im=l.re*r.im+l.im*r.re; //--- Result    return res;   } //+------------------------------------------------------------------+ //| Division                                                         | //+------------------------------------------------------------------+ complex complex::Div(const complex &l,const complex &r) const   { //--- Empty complex number    complex res(EMPTY_VALUE,EMPTY_VALUE); //--- Check for zero    if(r.re==0 && r.im==0)      {       Print(__FUNCTION__+": number is zero");       return(res);      } //--- Auxiliary variables    double e;    double f; //--- Selecting calculation variant    if(MathAbs(r.im)0)      {       ArrayResize(m_array,size);       //--- Fill with values       for(int i=0;i0)      {       out="{";       for(int i=0;i0? m_rows[0].Size():0); }    //--- Returns the value of the column in the form of a CRow row    CRow              GetColumnAsRow(const int col_index) const;    //--- Returns a string with the matrix values     string            String(void) const;    //--- The indexing operator returns a string by its number    CRow *operator[](int i) const        { return(GetPointer(m_rows[i]));        }    //--- Addition operator    CMatrix           operator+(const CMatrix &m);    //--- Multiplication operator    CMatrix           operator*(const CMatrix &m);    //--- Assignment operator    CMatrix          *operator=(const CMatrix &m);   }; //+------------------------------------------------------------------+ //| A default constructor, create an array of rows of zero size      | //+------------------------------------------------------------------+ CMatrix::CMatrix(void)   { //--- The zero number of rows in the matrix    ArrayResize(m_rows,0); //---     } //+------------------------------------------------------------------+ //| Returns the column value in the form of CRow                     | //+------------------------------------------------------------------+ CRow  CMatrix::GetColumnAsRow(const int col_index) const   { //--- A variable to get the values from the column    CRow row(); //--- The number of rows in the matrix    int rows=Rows(); //--- If the number of rows is greater than zero, execute the operation    if(rows>0)      {       //--- An array to receive the values of the column with index col_index       double array[];       ArrayResize(array,rows);       //--- Filling the array       for(int i=0;i=this[i].Size())            {             Print(__FUNCSIG__,": Error! Column number ",col_index,"> row size ",i);             break; // row will be uninitialized object            }          array[i]=this[i][col_index];         }       //--- Create a CRow row based on the array values       row=array;      } //--- Result    return(row);   } //+------------------------------------------------------------------+ //| Addition of two matrices                                         | //+------------------------------------------------------------------+ CMatrix CMatrix::operator+(const CMatrix &m)   { //--- The number of rows and columns in the passed matrix    int cols=m.Cols();    int rows=m.Rows(); //--- The matrix to receive the addition results     CMatrix res(rows); //--- The sizes of the matrix must match    if(cols!=Cols() || rows!=Rows())      {       //--- Addition impossible       Print(__FUNCSIG__,": Failed to add two matrices, their sizes are different");       return(res);      } //--- Auxiliary array    double arr[];    ArrayResize(arr,cols); //--- Go through rows to add    for(int i=0;i