#property copyright"Copyright 2011, MetaQuotes Software Corp."#property link"https://www.mql5.com"#property version"1.00"//+------------------------------------------------------------------+//| Класс-пример с несколькими типами доступа |//+------------------------------------------------------------------+class CBaseClass
{
private: //--- закрытый член недоступен из потомковint m_member;
protected: //--- защищенный метод доступен из базового класса и его потомковint Member(){return(m_member);}
public: //--- конструктор класса доступен всем
CBaseClass(){m_member=5;return;};
private: //--- закрытый метод для присвоения значения члену m_membervoid Member(int value) { m_member=value;};
};
//+------------------------------------------------------------------+//| Производный класс с ошибками |//+------------------------------------------------------------------+class CDerived: public CBaseClass // public наследование можно не указывать, оно по умолчанию
{
public:
void Func() // определим в потомке функцию с обращениями к членам базового класса
{
//--- попытка модификации закрытого члена базового класса
m_member=0; // ошибка, закрытый член базового класса никому не доступен
Member(0); // ошибка, закрытый метод базового класса не доступен в потомках
Strange thing about the constructor:
public: //--- конструктор класса доступен всем
CBaseClass(){m_member=5;return;};
Why is there a return operator here?
This is the first time I've seen this operator used in the constructor. In fact, the constructor is called automatically. And there will be an output anyway. Does this operator make sense in the constructor?
This is the first time I've seen this operator used in the constructor. In fact, the constructor is called automatically. And there will be an output anyway. Does this operator make sense in the constructor?
It is not needed in this example, but there can be complex initialization when early exit is needed.
The constructor and destructor are normal functions. Only the default constructor and destructor are called automatically. The others are called by the user.
The textbook gives this example in relation to polymorphism:
//--- Базовый классclass CShape
{
protected:
int m_type; // тип фигурыint m_xpos; // X - координата точки привязкиint m_ypos; // Y - координата точки привязкиpublic:
void CShape(){m_type=0;}; // конструктор, тип равен нулюint GetType(){return(m_type);};// возвращает тип фигурыvirtualdouble GetArea(){return (0); }// возвращает площадь фигуры
};
//--- производный класс Кругclass CCircle : public CShape // после двоеточия указывается базовый класс,
{ // от которого производится наследование private:
double m_radius; // радиус кругаpublic:
void CCircle(){m_type=1;}; // конструктор, тип равен 1 void SetRadius(double r){m_radius=r;};
virtualdouble GetArea(){return (3.14*m_radius*m_radius);}// площадь круга
};
class CSquare : public CShape // после двоеточия указывается базовый класс,
{ // от которого производится наследование private:
double m_square_side; // сторона квадратаpublic:
void CSquare(){m_type=2;}; // конструктор, тип равен 2 void SetSide(double s){m_square_side=s;};
virtualdouble GetArea(){return (m_square_side*m_square_side);}//площадь квадрата
};
There's one thing I don't understand. If we use child function objects for calls, i.e. derived methods CCircle and CSquare, then GetArea() area can be calculated bypassing declarations in base class. I.e. do not create virtual functions in base class at all, and in derived methods create a simple method and that's it! So why do we need a virtual function?
It's interesting to see an adequate and logical example, where you can see that virtual functions provide some benefit. Because what I saw was not logical, at least for me. I would like to understand it all the same.
The textbook gives this example in relation to polymorphism:
There's one thing I don't understand. If we use child function objects for calls, i.e. derived methods CCircle and CSquare, then GetArea() area can be calculated bypassing declarations in base class. I.e. do not create virtual functions in a base class at all, and in derived methods create a simple method and that's it! So why do we need a virtual function?
It's interesting to see an adequate and logical example, where you can see that virtual functions provide some benefit. Because what I saw was not logical, at least for me. I would like to understand it all the same.
This is the simplest sample for understanding polymorphism. To get it quickly.
There are complicated cases. You will apply it when you need it. There's no sense in bothering now. When the task is done, you'll have to think about it.
For example, I have a base class with all possible read/write interfaces. It also has private virtual methods (2 in total - read/write), which link this interface in the base class with derived classes. Actually the derived classes can be any where there is work with files (files, mapping, channels, internet). Each of the derived classes defines these virtual methods differently, but all classes have the same interface from the base class.
The textbook gives this example in relation to polymorphism:
There's one thing I don't understand. If we use child function objects for calls, i.e. derived methods CCircle and CSquare, then GetArea() area can be calculated bypassing declarations in base class. I.e. do not create virtual functions in base class at all, and in derived methods create a simple method and that's it! So why do we need a virtual function?
It's interesting to see an adequate and logical example, where you can see that virtual functions provide some benefit. Because what I saw was not logical, at least for me. I want to understand it all the same.
I will try to sketch a small sample:
#property strict#property show_inputsenum Mes_type {
m1,
m2
};
input Mes_type mes_t; // Выберите тип сообщенияclass Message {
public:
virtualvoid action() {};
};
class Mes1 : public Message {
public:
virtualvoid action() {Alert("Типичные ошибки в программах");}
};
class Mes2 : public Message {
public:
virtualvoid action() {Alert("Оффлайновые графики");}
};
voidOnStart() {
// Формируем входные данные для какого-то алгоритма//////////////////////////////////////////
Message *mes; //switch(mes_t) //
{ //case m1: //
mes = new Mes1; //break; //case m2: //
mes = new Mes2; //
} ///////////////////////////////////////////// Рабочий алгоритм//////////////////////////////////////////
mes.action(); ////////////////////////////////////////////delete mes;
}
Thanks to this structure, we won't need to get into working algorithm, which can be very big and complex (everything is simplified here), we will only need to add one more descendant, m3 in enumeration and one more case in switch. That is, we have unified the input data, which will avoid editing in the main part of the program.
Of course, this will only be appropriate if the working algorithm accepts a variety of types as input. If there is only one type, all of this is useless.
The textbook gives this example in relation to polymorphism:
There's one thing I don't understand. If we use child function objects for calls, i.e. derived methods CCircle and CSquare, then GetArea() area can be calculated bypassing declarations in base class. I.e. do not create virtual functions in a base class at all, and in derived methods create a simple method and that's it! So why do we need a virtual function?
It's interesting to see an adequate and logical example, where you can see that virtual functions provide some benefit. Because what I saw was not logical, at least for me. I would like to understand it all the same.
Here's a simple example:
CShape* GetNewShape()
{
if( ... ) // Здесь какое-то условие.
returnnew CCircle();
elsereturnnew CSquare();
}
CShape* M[10];
for( int i = 0; i < 10; i++ )
{
M[i] = GetNewShape();
}
double WholeArea = 0.0;
for( int i = 0; i < 10; i++ )
{
WholeArea += M[i].GetArea();
}
We use the GetArea() function without knowing which shape it is called for.
//---- SetColorBySend
TradingFunc::SetColorBySend (constcolor fc_ColorSendBuy, // Цвет открытия ордера на покупкуconstcolor fc_ColorSendSell) // Цвет открытия ордера на продажу
{
ColorBySend [2] = {fc_ColorSendBuy, fc_ColorSendSell};
}
The compiler is generally fighting this assignment of elements to theColorBySendarray like this:
What does this have to do with? Is it really necessary to assign values element by element? Isn't it possible to do it as a list? What is it related to? After all, that's how the assignment works even in the textbook...
The compiler swears at this assignment of elements to the ColorBySend array in general like this:
What does this have to do with? Is it really necessary to assign values element by element? Isn't it possible to do it as a list? What does it have to do with it? After all, this is how assignment is done even in the textbook...
A construct of the {something, something else} kind can only be an array of constants. But parameters passed into the function are substituted there that are actually local variables of the function. The modifier const in this case has no meaning as it only indicates that the passed value cannot be modified. As a result
{fc_ColorSendBuy, fc_ColorSendSell}
is a variable expression which the compiler cannot understand. Alas.
parameter names are not important... different names make sense so that something is not confused with something...
You can write some values in the function declaration,
and other values in the function itself
or you can name the parameters identically everywhere, whichever is more convenient for the code-writer
In the same textbook, the code came across:
Strange thing about the constructor:
Why is there a return operator here?This is the first time I've seen this operator used in the constructor. In fact, the constructor is called automatically. And there will be an output anyway. Does this operator make sense in the constructor?
In the same textbook, the code came across:
Strange thing about the constructor:
Why is there a return operator here?This is the first time I've seen this operator used in the constructor. In fact, the constructor is called automatically. And there will be an output anyway. Does this operator make sense in the constructor?
It is not needed in this example, but there can be complex initialization when early exit is needed.
The constructor and destructor are normal functions. Only the default constructor and destructor are called automatically. The others are called by the user.
The textbook gives this example in relation to polymorphism:
There's one thing I don't understand. If we use child function objects for calls, i.e. derived methods CCircle and CSquare, then GetArea() area can be calculated bypassing declarations in base class. I.e. do not create virtual functions in base class at all, and in derived methods create a simple method and that's it! So why do we need a virtual function?
It's interesting to see an adequate and logical example, where you can see that virtual functions provide some benefit. Because what I saw was not logical, at least for me. I would like to understand it all the same.
The textbook gives this example in relation to polymorphism:
There's one thing I don't understand. If we use child function objects for calls, i.e. derived methods CCircle and CSquare, then GetArea() area can be calculated bypassing declarations in base class. I.e. do not create virtual functions in a base class at all, and in derived methods create a simple method and that's it! So why do we need a virtual function?
It's interesting to see an adequate and logical example, where you can see that virtual functions provide some benefit. Because what I saw was not logical, at least for me. I would like to understand it all the same.
This is the simplest sample for understanding polymorphism. To get it quickly.
There are complicated cases. You will apply it when you need it. There's no sense in bothering now. When the task is done, you'll have to think about it.
For example, I have a base class with all possible read/write interfaces. It also has private virtual methods (2 in total - read/write), which link this interface in the base class with derived classes. Actually the derived classes can be any where there is work with files (files, mapping, channels, internet). Each of the derived classes defines these virtual methods differently, but all classes have the same interface from the base class.
The textbook gives this example in relation to polymorphism:
There's one thing I don't understand. If we use child function objects for calls, i.e. derived methods CCircle and CSquare, then GetArea() area can be calculated bypassing declarations in base class. I.e. do not create virtual functions in base class at all, and in derived methods create a simple method and that's it! So why do we need a virtual function?
It's interesting to see an adequate and logical example, where you can see that virtual functions provide some benefit. Because what I saw was not logical, at least for me. I want to understand it all the same.
I will try to sketch a small sample:
Thanks to this structure, we won't need to get into working algorithm, which can be very big and complex (everything is simplified here), we will only need to add one more descendant, m3 in enumeration and one more case in switch. That is, we have unified the input data, which will avoid editing in the main part of the program.
Of course, this will only be appropriate if the working algorithm accepts a variety of types as input. If there is only one type, all of this is useless.
The textbook gives this example in relation to polymorphism:
There's one thing I don't understand. If we use child function objects for calls, i.e. derived methods CCircle and CSquare, then GetArea() area can be calculated bypassing declarations in base class. I.e. do not create virtual functions in a base class at all, and in derived methods create a simple method and that's it! So why do we need a virtual function?
It's interesting to see an adequate and logical example, where you can see that virtual functions provide some benefit. Because what I saw was not logical, at least for me. I would like to understand it all the same.
Here's a simple example:
CShape* GetNewShape() { if( ... ) // Здесь какое-то условие. return new CCircle(); else return new CSquare(); } CShape* M[10]; for( int i = 0; i < 10; i++ ) { M[i] = GetNewShape(); } double WholeArea = 0.0; for( int i = 0; i < 10; i++ ) { WholeArea += M[i].GetArea(); }We use the GetArea() function without knowing which shape it is called for.I have this setter in a class:
The compiler is generally fighting this assignment of elements to the ColorBySend array like this:
'fc_ColorSendBuy' - constant expression required TradingFunc.mqh 91 23 'fc_ColorSendSell' - constant expression required TradingFunc.mqh 91 40 '{' - expression expected TradingFunc.mqh 91 22What does this have to do with? Is it really necessary to assign values element by element? Isn't it possible to do it as a list? What is it related to? After all, that's how the assignment works even in the textbook...I have this setter in a class:
The compiler swears at this assignment of elements to the ColorBySend array in general like this:
What does this have to do with? Is it really necessary to assign values element by element? Isn't it possible to do it as a list? What does it have to do with it? After all, this is how assignment is done even in the textbook...{fc_ColorSendBuy, fc_ColorSendSell}is a variable expression which the compiler cannot understand. Alas.