PLO. Application issues - page 11

 
Interesting:

How good it is to be able to read... :)

Also not bad approach, though as I understood both these approaches are designed for sending/reading only one parameter (albeit of different types).

But how to solve the problem, when you have a lot of parameters and you can't put all of them in a base class?

As far as I understand, you have to enter an index of the parameter you're passing (you can also create an array in a class with parameters stored by index)?

I don't understand it either...

In my example there is an index, only it is not numeric in an explicit form, but an enum....

 

Forget it, it's not worth it.

 

Interesting:

Yedelkin:

In general, following a discussion on the problemhttps://www.mql5.com/ru/forum/3566/page6#comment_58280 sent an application to the SR.

1. I don't know, I don't know.

I don't think the developers will take certain steps, sacrificing functionality for the sake of security (and rightly so on the one hand).

Reporting back.

The application was like this:
...

Suggestion:

1. Clarify the "Polymorphism" section in the "Polymorphism" handbook in terms of specifying how to correctly fill array shapes[10] with instances of classes derived from CShape (give an example).

2. check if the string is written correctly:

CShape[10] shapes;                       // массив объектов CShape

3. Explain whether or not to put curly brackets immediately after the name of the class being declared when declaring classes:

class CShape{};

class CCircle{} :public CShape

class CSquare{} :public CShape

Response:

Rashid Umarov 2011.04.11 15:17

At the time of writing the help, some points were not yet clear for documentation. We will fix this point and add the correct code. Thank you for your message.

An extended description will be added to Help, here is an extract from it:

We assume that our program uses objects of different types (CCircle and CSquare) but inherited from one base type CShape. Polymorphism allows us to create an array of objects of base type CShape, but when we declare this array, the objects themselves are still unknown and their type is undefined.

The decision of which type of object will be contained in each element of the array will be made during the execution of the program. This implies dynamic object creation for the corresponding classes and, therefore, the need to use object pointers instead of the objects themselves.

To create objects dynamically, the new operator is used; each such object must be independently and explicitly deleted by the delete operator. Therefore, we will declare an array of pointers of CShape type and create an object of the required type for each of its elements(new_class_name), as it is shown in the sample script:

//+------------------------------------------------------------------+

//| Script program start function                                    |

//+------------------------------------------------------------------+

void OnStart()

  {

//--- объявим массив указателей объектов базового типа 

   CShape *shapes[5];   // массив указателей на объекты CShape



//--- здесь заполняем массив производными объектами

//--- объявим указатель на объект типа CCircle

   CCircle *circle=new CCircle();

//--- задаем свойства объекта по указателю circle

   circle.SetRadius(2.5);

//--- поместим в shapes[0] значение указателя

   shapes[0]=circle;



//--- создаем еще один объект CCircle и запишем его указатель в shapes[1]

   circle=new CCircle();

   shapes[1]=circle;

   circle.SetRadius(5);



//--- тут мы намеренно "забыли" задать значение для shapes[2]

//circle=new CCircle();

//circle.SetRadius(10);

//shapes[2]=circle;



//--- для неиспользуемого элемента установим значение NULL

   shapes[2]=NULL;



//--- создаем объект CSquare и запишем его указатель в shapes[3]

   CSquare *square=new CSquare();

   square.SetSide(5);

   shapes[3]=square;



//--- создаем объект CSquare и запишем его указатель в shapes[4]

   square=new CSquare();

   square.SetSide(10);

   shapes[4]=square;



//--- массив указателей есть, получим его размер

   int total=ArraySize(shapes);

//--- пройдем в цикле по всем указателям в массиве 

   for(int i=0; i<5;i++)

     {

      //--- если по указанному индексу указатель является валидным

      if(CheckPointer(shapes[i])!=POINTER_INVALID)

        {

         //--- выведем в лог тип и площадь фигуры

         PrintFormat("Объект типа %d имеет площадь %G",

               shapes[i].GetType(),

               shapes[i].GetArea());

        }

      //--- если указатель имеет тип POINTER_INVALID

      else

        {

         //--- сообщим об ошибке

         PrintFormat("Объект shapes[%d] не инициализирован! Его указатель %s",

                     i,EnumToString(CheckPointer(shapes[i])));

        }

     }



//--- мы должны самостоятельно уничтожить все созданные динамические объекты

   for(int i=0;i<total;i++)

     {

      //--- удалять можно только объекты, чей указатель имеет тип POINTER_DYNAMIC

      if(CheckPointer(shapes[i])==POINTER_DYNAMIC)

        {

         //--- сообщим об удалении

         PrintFormat("Удаляем shapes[%d]",i);

         //--- уничтожим объект по его указателю

         delete shapes[i];

        }

     }

  }


Note that when deleting an object with the delete operator, you should check the type of its pointer. You can delete only objects with pointer POINTER_DYNAMIC, you will get an error for pointers of another type.

I think this example completely covers the idea of creating an array of pointers.
Rashid Umarov 2011.04.11 10:31

Thanks for the post, we have corrected №2 and №3. Will be in new versions of help



 

Question. The standard library uses the following lines

void CTrade::Request(MqlTradeRequest& request) const
  {...}

The Reference Manual says: " const specifier is not applicable to members of structures and classes". What does using const in a class method above mean, and what are the rules for using it in such cases?

Документация по MQL5: Стандартная библиотека
Документация по MQL5: Стандартная библиотека
  • www.mql5.com
Стандартная библиотека - Документация по MQL5
 

Yedelkin:

...............

What does the above use of const in a class method mean, and what are the rules for using it in such cases?

Oh yeah, I've been wondering that for a long time too. I want to use the language in a meaningful way, fully aware of the "rules of the game".
 
Yedelkin:

Question. The standard library uses the following lines

The Reference Manual says: " const specifier is not applicable to members of structures and classes". What does using const in a class method above mean, and what are the rules for using it in such cases?

A structure/class member is one thing, but a method is another.

A method described as const means that it does not change the state/members of its class. That is, after calling such a method, the internal state of the class remains unchanged. It is used to additionally tell the compiler to check for attempts to change class members.

 
Renat:

A structure/class member is one thing and a method is another.

A method described as const means that it does not change the state/members of its class. That is, the internal state of the class remains unchanged after this method is called. It is used to additionally tell the compiler to check for attempts to change class members.

Wow. Thank you! And I racked my brains.

 
TheXpert:
By the way, a logical question while we're on the subject -- there is no manual and it's not expected?

How could it be used? Because the threads don't interact with each other,

If the data could be freely transferred between threads, then, yes, there would be a need for such an instruction.

 
Damn, I thought I was writing something wrong :) now I know what. Not volatile of course -- mutable:))
 
class COracleTemplate
  {
private:
public:
   string            filename;
                     COracleTemplate(){Init();};
                    ~COracleTemplate(){DeInit();};
   virtual void      Init(){filename=this.Name();Print("loadSettings from ",filename);};
   virtual void      DeInit(){Print("saveSettings to ",filename);};
   virtual string    Name(){return("Prpototype");};
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CCO2:public COracleTemplate
  {
   virtual string    Name(){return("CO2");};
  };
class CH2O:public COracleTemplate
  {
   virtual string    Name(){return("H2O");};
  };
COracleTemplate* CO2,*H2O;
void OnStart()
  {
   CO2=new CCO2;
   Print(CO2.Name()," filename=",CO2.filename);
   delete CO2;
   
   H2O=new CH2O;
   Print(H2O.Name()," filename=",H2O.filename);
   delete H2O;
   
  }

Good afternoon.

Such a question.

On the code above

What did I do wrong or is it generally unattainable in MT5?

I want (as I think is obvious) - to get overridden names in filename variables...