MQL5中的OOP问题 - 页 11

 
Dmitry Fedoseev:

说到鸟......描述符也是指针。而且你知道,从这个词本身来看,没有什么变化,无论是描述符、指针、标识符。

长期以来,这些词语的实际执行情况对用户来说是隐蔽的。

我认为这或多或少是这样的

- 描述符--与系统中实现该功能的方法相联系

- 一个句柄--一切与描述符相同,但操作系统实现了它。

- 指针和标识符是用来与物理内存一起工作的。

 
Dmitry Fedoseev:

而如果你必须向一个函数传递一个指针,以便在该函数中创建一个对象,这就是它的工作原理。

class CObj{
   public:
   int f(){
      return(33);
   }
};

CObj * obj;

void OnStart(){
  z(obj);
  delete(obj);
}

void z(CObj & o){
   o = new CObj();
}
这其实就是你想知道的关于OOP的所有内容,但却不敢问))

嗯哼,天才。

这17行字实际上是你需要知道的关于费多谢夫作为一个程序员的资格的全部内容。

2019.07.05 15:19:56.309 'test13.mq5'中的无效指针 访问(11,5)。

 
Vasiliy Sokolov:

下午好。不管是在堆栈还是堆的背景下使用,计算机内存都具有相同的性能。 动态内存管理本身取决于垃圾收集器的实现:例如,它可以是Python中的引用计数(较慢的变体),或者在后台进程中通过执行图的遍历来分析对象的生成周期(Net CLR)。在MQL中使用的是哪种变体,我们不得而知,但我们可以假设它是非常有效的,因为MQL5的用户可以直接使用删除操作符,这大大简化了GC本身的工作。因此,你对使用new时的开销的担心是毫无根据的--请随意使用动态内存。

至于 "堆栈溢出",在现代系统中,你可能遇到这种情况的唯一途径是在使用复杂的递归或在递归算法中犯错。现代程序总是在虚拟地址空间的OC保护模式下工作,动态加载内存页,所以不用担心:堆栈不会溢出:)

谢谢你的巧妙解释。
出于某种原因,我认为在mql中,在栈上调用比在堆上调用要快,特别是由于我们不知道垃圾收集器的实现。
这就是为什么我有这样的问题,用什么来加快对象的创建,自动还是动态更好。
是的,我知道一切都取决于具体的任务,但举例来说,让我们来看看发送交易请求。
而我们的任务是创建最正确的对象,以实现快速处理性能。
我们有一个用户类,有描述交易请求的方法。
我们知道类实例的数量和它的方法。
而且正如你所建议的,"这个堆栈不会结束"。

因此,我的问题是:哪种方法对创建和删除对象更好?自动的还是动态的?
我有一个想法,要对一般的自动对象做合成管理。
也就是说,在用户的函数主体中声明自动对象。
这样,对象是在堆栈上创建的(理论上,它比堆快)。 我们不必担心自动删除对象,因为对象变量是在用户定义的函数中声明的
并且根据函数中的动态变量规则,自动对象将被用户函数本身额外检查是否被破坏。
这就是为什么我想听听这个分支的参与者的充分意见,他们在这方面的想法。

 
TheXpert:

嗯哼,天才。

这17行字实际上是你需要知道的关于费多塞耶夫作为一个程序员的资格的全部内容。

2019.07.05 15:19:56.309 'test13.mq5'中的无效指针访问(11,5)。

令人惊叹。而我都是在没有错误的情况下进行编译(现在),而且工作正常。

下一次,用Photoshop画。

 
Roman:

谢谢你的巧妙解释。
出于某种原因,我认为在mql栈上调用比在堆上调用要快,尤其是我们不知道垃圾收集器是如何实现的。
这就是为什么我有这样的问题,用什么来加快对象的创建,自动还是动态更好。
是的,我明白这一切都取决于具体的任务,但举例来说,让我们来看看发送交易请求。
而我们的任务是创建最正确的对象,以实现快速处理性能。
我们有一个用户类,有描述交易请求的方法。
我们知道类实例的数量和它的方法。
而且正如你所建议的,"这个堆栈不会结束"。

因此,我的问题是:哪种方法对创建和删除对象更好?自动的还是动态的?
我有一个想法,要对一般的自动对象做合成管理。
也就是说,在用户的函数主体中声明自动对象。
这样,对象是在堆栈上创建的(理论上,它比堆快)。 我们不必担心自动删除对象,因为对象变量是在用户定义的函数中声明的
并且根据函数中的动态变量规则,自动对象将被用户函数本身额外检查是否被破坏。
这就是为什么我想听听这个分支的参与者的充分意见,他们在这方面的想法。

你想得没错。访问用new创建的对象要慢得多。而且这里没有收垃圾的人。

 
Igor Makanu:

长期以来,这些词语的实际执行情况对用户来说是隐蔽的。

我认为是这样的。

- 描述符 - 与系统中实现该功能的方法相联系

- 一个句柄--一切与描述符相同,但操作系统实现了它。

- 一个指针和一个标识符意味着这是在物理内存中的操作。

而且对我们来说,它的工作方式也没有任何区别。

 

关于另一个问题的建议。如果你从CButton创建一个子类CMyButton,你可以创建一个按钮,然后在类外改变它的属性。 下面的工作是在OnInit()中完成的。

但是,如果我想在子类里面做额外的字段,并在新的函数中使用CButton类的内置属性,我怎样才能正确地做到这一点?

CButton类中,m_button类成员被声明在private部分。

#include <Controls\Button.mqh>

class CMyButton : public CButton
{ 
  private: 

  public: 
              CMyButton(void){}; 
             ~CMyButton(void){}; 
             
        bool    isPrevState;        // состояние кнопки на предыд.тике, true - была нажата     
        void    setButton();        // создаем кнопку
        void    setProp();          // задаем в ходе программы свойства
}; 

void CMyButton::setButton(void)
{
  // как в этой функции создать кнопку? Я не могу вызвать метод Create()
}

//+------------------------------------------------------------------------------------------------------------------+
//| 
//+------------------------------------------------------------------------------------------------------------------+

CButton Btn;
CMyButton MyBtn;

int OnInit()
  {
  
   Btn.Create(0, "Btn", 0, 50, 50, 120, 75);
   Btn.Text("Standart");
   MyBtn.Create(0, "MyBtn", 0, 50, 200, 150, 225);
   MyBtn.Text("MyBtn");
   
   return(INIT_SUCCEEDED);
  }
 
Dmitry Fedoseev:

是的,它删除并写了一条关于内存泄漏的信息,只是为了让那些写EA的程序员不至于生活得很无聊。

有趣的是,昨天还有一个内存泄漏,而今天根本不可能有。

说到鸟......描述符也是指针。而且你知道,这个词本身并没有改变任何东西,不管它是一个描述符、一个指针、一个标识符。

泄漏来自于进程的地址空间。当你在while(true)循环中泄密时,你的程序最终会在下次从堆中分配内存 时崩溃,因为堆已经用完了。
 
Dmitry Fedoseev:

而我都是在没有错误的情况下进行编译(现在),而且工作正常。

是的,已经有两个不相关的人在对你的代码的崩溃进行拍照了 )

你的代码不能正常工作,从代码本身就可以看出))

 
TheXpert:

是的,两个不相关的人已经在为你的代码拍照了 )

你的代码不能正常工作,从代码本身就可以看出))

刚才,想写同样的东西))))