エラー、バグ、質問 - ページ 2471

 
Igor Makanu:

CChartObjectLabelを作成する際、このコードで非初期化する際にインジケータ内のオブジェクトを削除しない理由を説明してください。

TFを切り替えるとジャーナルエントリーが表示されます: 2019.05.23 09:49:02.044 tstlabel EURUSD,M30: 2 objects of type CChartObjectLabel left.

テキストラベル(CChartObjectLabel)の作成をOnInit()でアンコメントすると、すべてが正しく動作するようになります。

CreateLabel() 関数にポインタを渡したが、後でOnDeinit()で削除 することができない

新しいオブジェクトlを作成します。しかも、削除されない。
 
Artyom Trishkin:
新しいlオブジェクトが作成されます。そして、それは削除されません。

元来

しかし、CChartObjectLabel *LabelUP,*LabelDN; 変数のスコープは、グローバルなのでしょうか?

では、コードのどの時点でも変数を変更することができるのですか?

CreateLabel()関数にポインタを渡しましたが、なぜ新しいコピーが作成されるのですか?

imhoは、正しく動作していません。

HH: OnInit()でオブジェクトを作成し、CreateLabel()でそれを扱う(つまり、オブジェクトを別々に作成し、ポインタで扱う)と、すべてが正しく動作します - しかし、他のコンパイラでは、新しいオブジェクトを作成する関数にポインタを渡すケースは記憶にありません - ポインタです、彼はポインタです!

 
Igor Makanu:

元来

が、私のスコープが グローバルなのか?- コードのどの部分でも変数を変更できるということでしょうか?

CreateLabel()にポインタを渡しましたが、なぜ新しいコピーを取得するのですか?

イマイチ、正しく動作しない。

新しいオブジェクトへのポインタを再割り当てすると、再割り当てされたポインタが指していた以前のオブジェクトは失われます。
 
Igor Makanu:

元来

しかし、CChartObjectLabel *LabelUP,*LabelDN; 変数のスコープは、グローバルなのでしょうか?

では、コードのどの時点でも変数を変更できるのですか?

CreateLabel()関数にポインタを渡しましたが、なぜ新しいコピーが作成されるのですか?

イミフ、正しく動作しない

を削除する必要があります。すでにオブジェクトとそれへのポインタが存在する。
 
Artyom Trishkin:
新しいオブジェクトへのポインタの再割り当てを行うと、再割り当てされたポインタが指していた以前のオブジェクトは失われてしまいます。

いいえ、ポインターはポインターです、MQLでは記述子です、ポイントではありません - しかし、オブジェクトの新しいコピーを作成するのは正しくありません、これは現在正しく動作しています。

//+------------------------------------------------------------------+
//|                                                         test.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#property strict
#property indicator_separate_window
#include <ChartObjects\ChartObjectsTxtControls.mqh>
CChartObjectLabel *LabelUP,*LabelDN;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   LabelUP=new CChartObjectLabel;
   LabelDN=new CChartObjectLabel;
   SetLabel(LabelUP,"LabelUP",0);
   SetLabel(LabelDN,"LabelDN",25);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   delete LabelUP;
   delete LabelDN;
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   return(rates_total);

  }
//+------------------------------------------------------------------+
void SetLabel(CChartObjectLabel *l,string name,int y)
  {
   l.Create(0,name,ChartWindowFind(),0,y);
   l.Color(clrYellow);
   l.FontSize(14);
   l.Description(name);
  }
//+------------------------------------------------------------------+

しかし、あなたの論理に従えば、このコードも関数SetLabel() でオブジェクト l のコピーを作成することになります- 私は参照ではなくポインタを渡しましたが?


アルチョム・トリシキン
newは削除すべきです。オブジェクトはすでに存在し、それへのポインタも存在する。

問題は、問題を解決する方法ではなく、なぜ変数CChartObjectLabel *LabelUP,*LabelDN;グローバルスコープで- ポインタを失った! - 。

 
Igor Makanu:

いいえ、ポインターはポインターです、MQLでは記述子です、ポイントではありません - しかし、オブジェクトの新しいコピーを作成するのは正しくありません、これは現在正しく動作しています。

しかし、あなたの論理に従えば、このコードも関数SetLabel() でオブジェクト l のコピーを作成することになります- 私は参照ではなく、ポインタを渡しましたか?

ここで、lはメソッドのパラメータで、必要なポインタを渡しています。ここは何も問題ない。ここでのポインタは、先に作成されたオブジェクトに 留まります。ここでは、新しいオブジェクトを作成し、前のオブジェクトを失ってポインタを再割り当てすることはしていない。
 
Artyom Trishkin:
ここで、lはメソッドのパラメータで、必要なポインタを渡している。ここは何も問題ない。ここでのポインタは、先に作成されたオブジェクトに 留まります。ここでは、新しいオブジェクトを作成し、前のオブジェクトを失ってポインタを再割り当てすることはしていない。

まだ正しく動作しない

MQLのこれらの「ポインタ」は、クラスのスコープで動作するように作られています。私はクラスを作成したくないので、グローバルポインタを宣言し、それを任意の関数に渡します。この関数でオブジェクトのディスクリプタを作成するという事実は、関数のローカルスコープから出たときにオブジェクトを破棄する理由にはなりません。

私は今少し忙しいですが、私はグラフィックスなしでテスト例を作る必要があります - 私はあなたがPOINTER_INVALID値を持つポインタで関数を入力した場合、あなたは同じPOINTER_INVALIDで終了します、すべてが正常に動作します、それはあなたが参照によってPOINTER_INVALID持つポインタを渡すことができないようです - ポインタへのアクセスエラーが発生します。

 
Igor Makanu:

どうせうまくいかない

MQLのこれらの「ポインタ」は、クラスのスコープで動作するように作られています。私はクラスを作成したくないので、単にドリルでポインタをグローバルスコープで宣言し、任意の関数に渡します。この関数でオブジェクトハンドルを作成するという事実は、関数のローカルスコープを終了したときにオブジェクトを破棄する理由にはなりません

もし、この関数にPOINTER_INVALIDの値で入ってきた場合、同じPOINTER_INVALIDの値で終了します。参照によって、すべてが正しく動作しますが、この関数にPOINTER_INVALIDの値を渡すことはできないようです - ポインタにアクセスするときにエラーが発生します

正確には、オブジェクトは破壊されない。メソッド内部で新しいオブジェクトが作成された後、すでに2つのオブジェクトが存在しています。そして、ポインタは1つだけです。それは、正式なパラメータとして メソッドに渡されました。したがって、オブジェクトの1つへのポインタを失うことになる。
 

テンプレート関数へのポインタを持つtypedefの宣言が可能であることに驚きました。
しかし、その幸せは長くは続かなかった。

template<typename T>
typedef bool (* callback)(T &);

template<typename T>
bool ff(T &){
   return true;
}

bool ff(int &){
   return true;
}


void OnStart(){
   int a;
   ff(a);
   
   callback<int> f_ptr_0 = ff;     //'<' - unexpected token     
   callback f_ptr_1 = ff;          //'ff' - function must have a body   
   callback f_ptr_2 = ff<int>;     //'ff<int>' - cannot resolve function address  //'ff<int>' - type mismatch   
}


テンプレート関数へのポインタを持つtypedefは、予定されている機能なのでしょうか?

 
typedef gardenのバグがもう一つ。
typedef void (* callback)(int &);

template<typename T>
void ff(T &){}


void OnStart(){
   int a = 0;
   //ff(a);                     //  если раскомментировать, то работает
   
   callback f_ptr = ff<int>;    //  'ff<int>' - function must have a body
   f_ptr(a);
}

typedef を使用する場合,明示的に特殊化されたテンプレート関数を使用すると,そのテ ンプレートのコードが生成されない