文章 "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

即没有"删除无效指针"的提示。在重新编译同一文件后(即第二次编译后),却显示了这样的信息:

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 时,它只给出了

即没有"删除无效指针 "的提示。在重新编译同一文件后(即第二次编译后),却显示了这样的信息:

自文章发表以来,终端对删除无效指针的反应是否有所改变?XP, 32
感谢您的留言。已修复。行为发生了变化,现在只有在编译调试时才会生成 "删除无效指针" 信息
 

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

好的,我们希望看到对这篇文章的澄清。
 

为什么这一行会导致构造函数运行?

 CItem* array1[5];

而这一行不会:

CObjectC *pObjectC;
?
 
新操作符只是为了使类成为动态的?但是,如果动态数组 是 "在第一对方括号中带有未指定值的数组",那么什么是动态类呢?
Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
  • www.mql5.com
Основы языка / Типы данных / Объект динамического массива - Документация по MQL5
 
Burgunsky:

为什么这一行会导致构造函数被调用:

我检查过了,没有调用构造函数,请附上整个代码。
 
Burgunsky:

为什么这一行会导致构造函数运行: CItem* array1[5];、

而这一行不会: CObjectC *pObjectC; ?

我的理解是

CItem* array1[5];

行本身并不会导致构造函数启动。下面是文章中更完整的代码:

void OnStart()
  {
//--- 声明指向对象的第一个数组指针
   CItem* array1[5];
//--- 声明指向对象的第二个数组指针
   CItem* array2[5];
//--- 现在让我们填充循环中的数组
   for(int i=0;i<5;i++)
     {
      //--- 第一个数组的指针将由操作符 new 创建
      array1[i]=new CItem;
      //--- 第二个数组的指针将从第一个数组复制过来
      array2[i]=array1[i];
     }
构造函数不是在声明第一个指针数组时调用的,而是在循环中使用new 操作符填充该数组时调用的。
 
Burgunsky:
新操作符只是为了使类成为动态的?但是,如果动态数组 是 "在第一对方括号中带有未指定值的数组",那么什么是动态类呢?
我的理解是,编程中的 "动态 "一词是多义词。说到类,有一个对立面:"自动创建的对象 "与 "动态创建的对象"。它们之间的区别与全局变量和局部变量之间的区别大致相同。换句话说,"动态创建的对象 "是 "暂时 "创建的对象,它的生命周期是从新操作符创建的那一刻到删除操作符删除的那一刻。
 

但问题依然存在:

通过 new 操作符创建动态对象的意义何在?

自动创建对象时,类对象是在堆栈中创建的,在执行时间 上比动态对象快。

动态创建对象时,类对象是在内存(堆)中创建的,同时使用操作系统内存管理器,这个过程比较慢。

这里有一个问题:如果自动创建更快,为什么还要创建动态对象?是为了防止堆栈溢出吗?

[删除]  
为方便起见,所附源代码 文件和 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.