PLO. Application issues - page 5

 

Somehow, the question of whether or not multi-purposing affects CPU code processing speed has gone completely unnoticed(2011.04.04 21:58).

If the question seems incorrect, silly, etc. - then write so.

 
Yedelkin:

Somehow, the question of whether or not multi-purposing affects CPU code processing speed has gone completely unnoticed(2011.04.04 21:58).

If the question seems incorrect, silly, etc. - just write it so.

The question is perfectly logical, the answer is no, it doesn't.

2011.04.09 10:21:31     Черновик 31 (GBPUSD,H1) время c обёртками=1656
2011.04.09 10:21:29     Черновик 31 (GBPUSD,H1) время без обёртки=1766


class CA
  {
private:
   uint              func1(int count){return(func2(count));};
   uint              func2(int count){return(func3(count));};
   uint              func3(int count){return(func4(count));};
   uint              func4(int count){return(func5(count));};
   uint              func5(int count){return(func6(count));};
   uint              func6(int count){return(func7(count));};
   uint              func7(int count){return(func8(count));};
   uint              func8(int count){return(func9(count));};
   uint              func9(int count)
     {
      uint start=GetTickCount();
      double a=123456.4567879;double b=234.568;double temp;
      for(int i=0;i<count;i++)
        {
         if(i%2==0)temp=a/b;
         else temp=a*b;
        }
      return(GetTickCount()-start);
     };
public:
                     CA(void){};
                    ~CA(void){};
   uint              func(int count){return(func1(count));};

  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
          Print("время без обёртки=",  func(100000000));
   CA a; Print("время c обёртками=",a.func(100000000));
  }
//+------------------------------------------------------------------+
uint func(int count)
  {
   uint start=GetTickCount();
   double a=123456.4567879;double b=234.568;double temp;
   for(int i=0;i<count;i++)
     {
      if(i%2==0)temp=a/b;
      else temp=a*b;
     }
   return(GetTickCount()-start);
  }
//+------------------------------------------------------------------+
 

I got it! Well, you've given me a lot of encouragement! I'll be doubling the pleasure of stamping nested methods now :)

Urain, thanks for the example! While you have no programming experience, sometimes it is difficult to guess yourself to check and write correct code for it. And here everything is clear and understandable.

 

Question. Can an instance of a child class delete itself? In other words, will such a construct work?

class C_A
  {
public:
                     C_A(){};
                    ~C_A(){};
   void Del(C_A *p)
     {
      if(CheckPointer(p)==POINTER_DYNAMIC)
        {
         delete p;
        }
     }
  };
class C_B : public C_A
  {
public:
                     C_B(){};
                    ~C_B(){};
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   C_A *pointer=new C_B;
   pointer.Del(pointer);
  }
The compiler doesn't complain about this construct.
 
Yedelkin:

Question. Can an instance of a child class delete itself? In other words, will this construction work?

The compiler doesn't complain about this construct.

If I understand it correctly, I don't like pointers (and I don't use them often, especially in MQL5), the child should look like this

class C_B : public C_A
{
public:
                     C_B(){};
                    ~C_B(){};

   void Del(C_B *p)
     {
      if(CheckPointer(p)==POINTER_DYNAMIC)
        {
         delete p;
        }
     }
};

Therefore, the application would look like this

void OnStart()
{
C_B *pointer=new C_B;
pointer.Del(pointer);
}

PS

Is it a bug (or a feature of the compiler) that the compiler missed it?

Of course, we can assume that the descendant passed the class we need but the structures and functionality of the two classes might be very different. So what happens then?

C_A *pointer=new C_B;
 

And when using the initial code like this, a memory leak occurs at all, although all the compiler checks have been passed (and it hasn't even mentioned any possible problems)

void OnStart()
{
C_B *pointer=new C_B;
pointer.Del(pointer);
}

Here is the result (I understand that the pointer object is not correctly deleted because of the memory leak):

2011.04.09 19:21:07    Forum (EURUSD,D1)    16 bytes of leaked memory
2011.04.09 19:21:07    Forum (EURUSD,D1)    1 object of type C_B left
2011.04.09 19:21:07    Forum (EURUSD,D1)    1 undeleted objects left
 
Interesting:

If I understand it correctly, I don't like pointers (and I don't use them often, especially in MQL5), then the descendant should look like this

Look. I've declared void Del(C_A *p) method with modifier public in the parent class. So, the child class has fully inherited this method. So I don't need to re-declare the same method in the child class. As for
C_A *pointer=new C_B;
I got this idea from tetris, and it works just fine for me. Of course, it wouldn't be right to use this line outright, but it's very suitable for similar purposes to those solved in tetris.
 
Yedelkin:

Somehow, the question of whether or not multi-purposing affects the speed of code processing by the processor(2011.04.04 21:58) is left completely unattended.

If the question seems incorrect, silly, etc. - just write it.

The answer to logic -- the simpler and more logical the primitives, the more efficient the optimizer will be.

The main thing is not to overdo it :)

 

Slightly modified the script code:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_A
  {
public:
                     C_A(){ Print("Запущен класс С_А"); };
                    ~C_A(){Print("Закрыт класс С_А");};
   void Del(C_A *p)
     {
      if(CheckPointer(p)==POINTER_DYNAMIC)
        {
         delete p;
         Print("Удалён объект p");
        }
     }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B : public C_A
  {
public:
                     C_B(){ Print("Запущен класс С_В"); };
                    ~C_B(){Print("Закрыт класс С_В");};
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   C_A *pointer=new C_B;
   if(pointer!=NULL) Print("указатель pointer проинициализирован");
   pointer.Del(pointer);
  }

Outputs

EL      0       ttttttttttttt (EURUSD,M1)       15:08:27        Запущен класс С_А
MS      0       ttttttttttttt (EURUSD,M1)       15:08:27        Запущен класс С_В
DJ      0       ttttttttttttt (EURUSD,M1)       15:08:27        указатель pointer проинициализирован
IH      0       ttttttttttttt (EURUSD,M1)       15:08:27        Закрыт класс С_В
CG      0       ttttttttttttt (EURUSD,M1)       15:08:27        Закрыт класс С_А
RO      0       ttttttttttttt (EURUSD,M1)       15:08:27        Удалён объект p
 
Yedelkin:
Look. I declared void Del(C_A *p) method with modifier public in the parent class. So the child class has fully inherited this method. So I don't need to re-declare the same method in the child class. As for this idea, I got it from tetris and it worked out very well for me. Of course, it wouldn't be correct to use this string outright, but it's very suitable for similar purposes to those solved in tetris.

Even assuming void Del(C_A *p) in the ancestor is sufficient to delete any descendant pointer, I don't see the point in using

C_A *pointer=new C_B;

PS

The only place where I can imagine the need for such an approach is creating an array of miscellaneous objects that are descendants of the same class (alternatively, passing a parameter of the "base" class type into a function or procedure).