記事"MQL5でのオブジェクト作成と削除の順番"についてのディスカッション

 

新しい記事 MQL5でのオブジェクト作成と削除の順番 はパブリッシュされました:

MQL5プログラムでは、すべてのオブジェクトはカスタムオブジェクトだろうと、動的配列またはオブジェクト配列は特定の方法で作成され削除されます。 しばしば オブジェクトは他のオブジェクトの一部で、非初期化のオブジェクト削除の順は特に重要になります。本記事ではオブジェクトを使用するメカニズムの例を紹介します。

MQL5プログラムは オブジェクト指向プログラミング (OOP)コンセプトで書かれており、カスタムライブラリを作成する新しい可能性が開けただけでなく、他の開発者の完全で試験済のクラスを使うことができるようになりました。MetaTrader 5 クライアントターミナルの中にある 標準 ライブラリでは数千のメソッドを含む数百のクラスがあります。

OOPをフルに活用するには、 MQL5プログラムにおけるオブジェクトの作成と削除の詳細について明らかにしなければなりません。オブジェクトの作成と削除 は簡潔にドキュメンテーションに書かれています。本記事はこのトピックを例で説明します。

作者: MetaQuotes Software Corp.

 

LocalVar_TestScript_2.mq5を 初めて実行すると、次のような結果しか得られない。

PO      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::CItem Constructor
LD      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::CItem Constructor
HJ      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::CItem Constructor
DS      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::CItem Constructor
PH      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::CItem Constructor
GP      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::~CItem Destructor
KF      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::~CItem Destructor
OM      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::~CItem Destructor
CD      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::~CItem Destructor
GK      0       LocalVar_TestScript_2 (EURGBP,M1)       12:08:19        CItem::~CItem Destructor

つまり、"delete invalidpointer"という メッセージは表示されない。同じファイルを再コンパイルすると(つまり2回目のコンパイル後)、このように表示されます:

PQ      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::CItem Constructor
LH      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::CItem Constructor
HO      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::CItem Constructor
DF      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::CItem Constructor
PL      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::CItem Constructor
GR      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::~CItem Destructor
KK      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::~CItem Destructor
OP      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::~CItem Destructor
CF      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::~CItem Destructor
GO      0       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        CItem::~CItem Destructor
PH      1       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        敤敬整渠湯搠湹浡捩漠橢捥t
RP      1       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        敤敬整渠湯搠湹浡捩漠橢捥t
DH      1       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        敤敬整渠湯搠湹浡捩漠橢捥t
FP      1       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        敤敬整渠湯搠湹浡捩漠橢捥t
HH      1       LocalVar_TestScript_2 (EURUSD,H1)       12:09:12        敤敬整渠湯搠湹浡捩漠橢捥t
無効なポインタを削除したときのターミナルの反応は、この記事が公開されたときから変更されているのでしょうか?XP, 32
 
Yedelkin:

LocalVar_TestScript_2.mq5を 初めて実行すると、次のような結果しか得られない。

つまり、"delete invalid pointer "という メッセージは表示されない。同じファイルを再コンパイルすると(つまり2回目のコンパイル後)、このように表示されます:

無効なポインタを削除したときのターミナルの反応は、この記事が公開されたときから変更されているのでしょうか?XP, 32
メッセージありがとうございます。修正しました。動作が変更され、デバッグ用のコンパイル時のみ「無効なポインタを 削除」 メッセージが生成される ようになりました。
 

mql5:
Спасибо за сообщение. Исправлено. Поведение изменилось, теперь сообщение "delete invalid pointer" выдаётся только при компиляции под отладку.

OK、記事の明確化をお願いしたい。
 

なぜこの行ではコンストラクタが実行されるのですか?

 CItem* array1[5];

これは実行されない:

CObjectC *pObjectC;
?
 
new演算子はクラスをダイナミックにするためだけに必要なのだろうか?しかし、もし動的配列が「最初の角括弧のペアに未指定の値を持つ配列」だとしたら、動的クラスとは何だろうか?
Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
  • www.mql5.com
Основы языка / Типы данных / Объект динамического массива - Документация по MQL5
 
Burgunsky:

なぜこの行でコンストラクタが呼び出されるのでしょうか?

確認しましたが、コンストラクタは呼び出されていませんでした。
 
Burgunsky:

また、なぜこの行でコンストラクタが実行されるかというと、CItem* array1[5];である、

しかし、この行は実行されない: CObjectC *pObjectC; ?

この行は

CItem* array1[5];

この行だけではコンストラクタは起動しない。以下は、その記事にあるより完全なコードである:

void OnStart()
  {
//--- オブジェクトへのポインタの最初の配列を宣言する。
   CItem* array1[5];
//--- オブジェクトへのポインタの2番目の配列を宣言する。
   CItem* array2[5];
//--- では、ループ内の配列を埋めてみよう。
   for(int i=0;i<5;i++)
     {
      //--- 最初の配列のポインタは、new演算子によって作成される。
      array1[i]=new CItem;
      //--- 2番目の配列のポインタは、1番目の配列からコピーされる。
      array2[i]=array1[i];
     }
コンストラクタが呼び出されるのは、最初のポインタ配列を宣言するときではなく、new 演算子を使ったループでこの配列を埋めるときである。
 
Burgunsky:
new演算子はクラスをダイナミックにするためだけに必要なのだろうか?しかし、動的配列が「最初の角括弧のペアに未指定の値を持つ配列」だとしたら、動的クラスとは何だろう?
プログラミングにおける「動的」という言葉は多義的であると私は理解した。クラスに関しては、「自動的に生成されるオブジェクト」と「動的に生成されるオブジェクト」という対立関係がある。両者の違いは、グローバルレベルで宣言された変数とローカルレベルで宣言された変数の違いとほぼ同じです。言い換えれば、「動的に生成されるオブジェクト」は「しばらくの間」生成されるオブジェクトであり、その寿命はnew演算子によって生成された瞬間からdelete演算子によって削除される瞬間までである。
 

しかし、まだ疑問がある:

new演算子を使ってダイナミック・オブジェクトを作成する意味はあるのだろうか?

オブジェクトを自動的に作成する場合、クラス・オブジェクトはスタックに作成されるため、実行時間では ダイナミック・オブジェクトよりも速い。

動的にオブジェクトを作成する場合、クラス・オブジェクトはOSのメモリー・マネージャーを使いながらメモリー上(ヒープ内)に作成されるため、処理は遅くなります。

ここで疑問がある。自動生成の方が速いなら、なぜダイナミック・オブジェクトが生成されるのか?スタックのオーバーフローを防ぐため?

削除済み  
添付のソース コードファイルとHTMLコード内のソースコードインセットは、お客様の便宜のために完全にポルトガル語に翻訳されました。
MQL5.community - User Memo
MQL5.community - User Memo
  • 2010.02.25
  • MetaQuotes Software Corp.
  • www.mql5.com
You have just registered and most likely you have questions such as, "How do I insert a picture to my a message?" "How do I format my MQL5 source code?" "Where are my personal messages kept?" You may have many other questions. In this article, we have prepared some hands-on tips that will help you get accustomed in MQL5.community and take full advantage of its available features.