forked from airat77786/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());
| |||
}
| |||
//+------------------------------------------------------------------+
|