PLOです。アプリケーションの問題 - ページ 5

 

マルチパーパス化がプロセッサのコード処理速度に影響を 与えるかどうかという問題は、なぜか全く放置されている(2011.04.04 21:58)。

問題が間違っている、ばかばかしいなどと思われる場合。- であれば、そう書いてください。

 
Yedelkin:

マルチパーパス化がCPUのコード処理速度に影響を 与えるかどうかという問題は、なぜか全く注目されていない(2011.04.04 21:58)。

問題が間違っている、ばかばかしいなどと思われる場合。- と書けばいいのです。

この質問は完全に論理的で、答えは「いいえ、そうではありません」です。

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);
  }
//+------------------------------------------------------------------+
 

やったぜ!いやー、いろいろと励まされましたねー。これからは入れ子方式でスタンプを押す楽しみが倍増しますよ :)

Urain さん、お手本ありがとうございますプログラミングの経験がないうちは、自分で推測して確認し、正しいコードを書くことが難しい場合もあります。そして、ここではすべてが明確で理解しやすい。

 

質問です。子クラスのインスタンスは、自分自身を削除することができますか?つまり、このような構成はうまくいくのでしょうか?

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);
  }
コンパイラは、この構成について文句を言いません。
 
Yedelkin:

質問です。子クラスのインスタンスは、自分自身を削除することができますか?つまり、この工事で大丈夫なのか?

コンパイラは、この構成について文句を言いません。

私の理解が正しければ、ポインターは好きではなく(特にMQL5ではあまり使いません)、子は次のようになります。

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

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

したがって、アプリケーションは次のようになります。

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

追記

コンパイラが見落としたのは、バグ(またはコンパイラの機能)なのでしょうか?

もちろん、子孫から必要なクラスが渡されたと仮定することはできますが、2つのクラスの構造や機能は大きく異なる可能性があります。では、どうなるのでしょうか?

C_A *pointer=new C_B;
 

そして、このような初期コードを使用すると、コンパイラのチェックはすべて通過しているにもかかわらず、メモリリークがまったく発生しません(考えられる問題点についても言及されていません)。

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

以下はその結果です(メモリリークのため、ポインタオブジェクトが正しく削除されないと理解しています)。

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:

私の理解が正しければ、ポインターは好きではない(特にMQL5ではあまり使わない)ので、子孫は次のようになるはずです。

見てください。親クラスでvoid Del(C_A *p)メソッドをpublic修飾子付きで宣言しています。つまり、子クラスはこのメソッドを完全に継承しているのです。だから、子クラスで同じメソッドを再宣言する必要はないんだ。については
C_A *pointer=new C_B;
このアイデアはテトリスから得たもので、私にとってはうまくいっています。もちろん、この線をそのまま使うのはおかしいのですが、テトリスで解いたような用途には非常に適しています。
 
Yedelkin:

マルチパーパス化がプロセッサのコード処理速度に影響を 与えるかどうかという問題は、なぜか全く放置されている(2011.04.04 21:58)。

問題が間違っている、ばかばかしいなどと思われる場合。- を書くだけです。

論理の答え--プリミティブがシンプルで論理的であればあるほど、オプティマイザはより効率的になる。

要はやり過ぎないことです :)

 

スクリプトのコードを若干修正。

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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);
  }

出力

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:
見てください。親クラスでvoid Del(C_A *p)メソッドをpublic修飾子付きで宣言しました。つまり、子クラスはこのメソッドを完全に継承しているのです。だから、子クラスで同じメソッドを再宣言する必要はないんだ。このアイデアに関しては、テトリスから得たもので、私にとっては非常にうまくいったものです。もちろん、この文字列をそのまま使うのは正しくないが、テトリスで解いたのと同じような目的で使うには非常に適している。

先祖の void Del(C_A *p) が子孫のポインタを削除するのに十分であると仮定しても、私は

C_A *pointer=new C_B;

追記

このようなアプローチの必要性を想像できるのは、同じクラスの子孫である雑多なオブジェクトの配列を作成する場合だけです(代わりに、「ベース」クラスの型のパラメータを関数やプロシージャに渡します)。