forked from rosh/MQL5Book
212 lines
5.9 KiB
MQL5
212 lines
5.9 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| Shapes1.mq5 |
| |
//| Copyright 2021, MetaQuotes Ltd. |
| |
//| https://www.mql5.com |
| |
//+------------------------------------------------------------------+
| |
#include "..\..\Include\TypeName.mqh"
| |
| |
struct Pair
| |
{
| |
int x, y;
| |
Pair(int a, int b): x(a), y(b)
| |
{
| |
Print(__FUNCSIG__, " ", x, " ", y);
| |
}
| |
~Pair()
| |
{
| |
Print(__FUNCSIG__, " ", x, " ", y);
| |
}
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| Base shape class for drawing |
| |
//+------------------------------------------------------------------+
| |
class Shape
| |
{
| |
protected:
| |
// int x, y; // center coordinates
| |
Pair coordinates; // the same in the form of embedded object
| |
color backgroundColor;
| |
const string type;
| |
| |
public:
| |
Shape() : // default constructor
| |
// x(0), y(0),
| |
coordinates(0, 0),
| |
backgroundColor(clrNONE),
| |
type(TYPENAME(this))
| |
{
| |
Print(__FUNCSIG__, " ", &this);
| |
}
| |
| |
Shape(int px, int py, color back, string t = NULL) :
| |
// x(px), y(py),
| |
coordinates(px, py),
| |
backgroundColor(back),
| |
type(t != NULL ? t : TYPENAME(Shape))
| |
{
| |
Print(__FUNCSIG__, " ", &this);
| |
}
| |
| |
Shape(const Shape &source) : // copy-constructor
| |
coordinates(source.coordinates.x, source.coordinates.y),
| |
backgroundColor(source.backgroundColor),
| |
type(source.type)
| |
{
| |
}
| |
| |
~Shape()
| |
{
| |
Print(__FUNCSIG__, " ", &this);
| |
}
| |
| |
// unreal implementation of draw:
| |
// just to demonstrate 'this' dereferencing
| |
// warning: declaration of 'backgroundColor' hides member
| |
void draw(string backgroundColor = NULL)
| |
{
| |
// ... use the string, maybe lookup color by description
| |
| |
// misused name
| |
// warning: implicit conversion from 'number' to 'string'
| |
backgroundColor = clrBlue;
| |
this.backgroundColor = clrBlue; // ok
| |
| |
{
| |
// warning: declaration of 'backgroundColor' hides local variable
| |
bool backgroundColor = false;
| |
// ... do something
| |
this.backgroundColor = clrRed; // ok
| |
}
| |
// ...
| |
}
| |
| |
Shape *setColor(const color c)
| |
{
| |
backgroundColor = c;
| |
return &this;
| |
}
| |
| |
Shape *moveX(const int x)
| |
{
| |
coordinates.x += x;
| |
return &this;
| |
}
| |
| |
Shape *moveY(const int y)
| |
{
| |
coordinates.y += y;
| |
return &this;
| |
}
| |
| |
string toString() const
| |
{
| |
return type + " " + (string)coordinates.x + " " + (string)coordinates.y;
| |
}
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| Rectangle shape |
| |
//+------------------------------------------------------------------+
| |
class Rectangle : public Shape
| |
{
| |
protected:
| |
int dx, dy; // size (width, height)
| |
| |
public:
| |
Rectangle(int px, int py, int sx, int sy, color back) :
| |
Shape(px, py, back, TYPENAME(this)), dx(sx), dy(sy)
| |
{
| |
Print(__FUNCSIG__, " ", &this);
| |
}
| |
Rectangle(const Rectangle &other) :
| |
Shape(other), dx(other.dx), dy(other.dy)
| |
{
| |
}
| |
~Rectangle()
| |
{
| |
Print(__FUNCSIG__, " ", &this);
| |
}
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| Ellipse shape |
| |
//+------------------------------------------------------------------+
| |
class Ellipse : public Shape
| |
{
| |
protected:
| |
int dx, dy; // large and small radiuses
| |
| |
public:
| |
Ellipse(int px, int py, int rx, int ry, color back) :
| |
Shape(px, py, back, TYPENAME(this)), dx(rx), dy(ry)
| |
{
| |
Print(__FUNCSIG__, " ", &this);
| |
}
| |
~Ellipse()
| |
{
| |
Print(__FUNCSIG__, " ", &this);
| |
}
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| Triangle shape |
| |
//+------------------------------------------------------------------+
| |
class Triangle: public Shape
| |
{
| |
int dx; // single side
| |
public:
| |
Triangle(int px, int py, int side, color back) :
| |
Shape(px, py, back, TYPENAME(this)), dx(side)
| |
{
| |
Print(__FUNCSIG__, " ", &this);
| |
}
| |
~Triangle()
| |
{
| |
Print(__FUNCSIG__, " ", &this);
| |
}
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| Script program start function |
| |
//+------------------------------------------------------------------+
| |
void OnStart()
| |
{
| |
Shape s;
| |
// Print(s); // 's' - objects are passed by reference only
| |
Print(&s); // ok: &s means a pointer to s
| |
// errors: cannot access to protected member declared in class 'Shape'
| |
// Print(s.x, " ", s.y);
| |
| |
// method chaining through 'this'
| |
s.setColor(clrWhite).moveX(80).moveY(-50);
| |
| |
Rectangle r(100, 200, 75, 50, clrBlue);
| |
Ellipse e(200, 300, 100, 150, clrRed);
| |
| |
/*
| |
// copy-construction
| |
Shape s2(s); // ok: syntax 1
| |
Shape s3 = s; // ok: syntax 2
| |
| |
// error: attempting to reference deleted function
| |
// 'void Shape::operator=(const Shape&)'
| |
// function 'void Shape::operator=(const Shape&)' was implicitly
| |
// deleted because member 'type' has 'const' modifier
| |
// Shape s4;
| |
// s4 = s;
| |
| |
Shape s5(r); // ok: copy derived to base
| |
| |
// error: 'Rectangle' - no one of the overloads
| |
// can be applied to the function call
| |
Rectangle r4(s);
| |
*/
| |
| |
// Print(TYPENAME(s), " ", TYPENAME(r)); // Shape Rectangle
| |
| |
Print(s.toString());
| |
Print(r.toString());
| |
Print(e.toString());
| |
}
| |
//+------------------------------------------------------------------+
|