MQL5Book/Scripts/p3/Shapes1.mq5

213 lines
5.9 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:09:41 +02:00
//+------------------------------------------------------------------+
//| 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());
}
//+------------------------------------------------------------------+