在休息室谈论巴解组织的问题 - 页 6

 
George Merts:

这个(以及所有以下划线开头的)是该类的一个受保护的函数。

好了,它们合二为一了!

只有一个函数--Compare(),但我们必须通过被传递的键进行比较。相应地,选择了一个特定的被保护的功能。这就是为什么它们被保护起来(protected),这样用户就不能访问它们--它们只能从Compare()中调用,这一点用下划线表示。

这也是代码设计 规则之一--以下划线开头的函数不打算被用户调用,它只为某些课内任务服务。对它的访问是受限制的。

但为什么要玩这种马戏团的把戏,因为用经典的东西做任何事情都要容易得多。使用包装函数和大括号来隐藏嵌套的变量和函数,并防止对它们的访问,你就会很高兴。你用这些护身符只会迷惑自己和别人......

 
Andrei:

但为什么要玩这种马戏团的把戏,因为一切都可以通过经典的方式来做。使用包装函数和大括号来隐藏嵌套的变量和函数,并防止对它们的访问,你就会很高兴。你用这些护身符只会迷惑自己和别人......

我不明白...Protected是一个函数的访问修饰符。也就是说,使用了一个保护者函数,它只能从一个类或其后代的函数中访问。另外,对我个人来说,下划线意味着有一些隐含的假设,在使用它时必须考虑到。

Dennis Kirichenko 正确地指出--你可以在一个Compare()函数中写下一切。但那样的话就会有两打屏幕,查看起来就不现实了,而且比现在更难修改。

我在Compare()函数中只留下了按键选择器,而对特定按键进行比较的代码则放在单独的函数中。由于这些函数具有高度的上下文特性,它们被声明在类的保护部分,这样它们就可以从该类的另一个函数或子类中被专门访问。 而且,为了提醒自己这些函数是为了在另一个函数中执行一个特定的狭窄任务--我用下划线开始它们。如果我将来遇到这样的函数--我会立即发现,在调用它时需要考虑到一些隐含的假设。

看来,你(姑且称为 "你")并不十分了解什么是访问修饰语,以及为什么需要它们。

 
George Merts:

我不明白...Protected是一个函数的访问修饰符。也就是说,使用了一个保护者函数,它只能从一个类或其后代的函数中访问。另外,下划线符号对我个人来说意味着使用它时需要考虑一些隐含的假设。

好吧,你可以用经典的方式限制对一个函数的访问,而不需要任何OOP。
 
Artyom Trishkin:

但不能有人身侮辱...

请清理该主题的水灾,只留下Alexey Volchanskiy的 教育性帖子。
 
Andrei:
好吧,你可以通过经典的方法限制对函数的访问,而不需要任何OOP。

如何?

这里的任务是--使其在将来修改代码时,不可能在 "任何地方 "提取和使用某个函数。如何在公有-保护-私有修改器的帮助下,在没有OOP-限制访问 类空间的情况下做到这一点?

 

显然,静态和常量(这不是OOP)是不需要的。

至于OOP,非常有趣,下面这个有着广泛实际应用的函数(一点也不抽象),在程序式中会是什么样子?

关于交易、自动交易系统和策略测试的论坛

组织一个订单溢出周期

fxsaber, 2017.10.18 12:29

不参考历史的版本。
struct HISTORY_UNIT
{
  long Ticket;
  int Type;
  double Lots; 
    
  HISTORY_UNIT( void ) : Ticket(::OrderTicket()), Type(::OrderType()), Lots(::OrderLots())
  {
  }

  bool operator !=( const HISTORY_UNIT &Unit ) const
  {
    return((this.Ticket != Unit.Ticket) || (this.Type != Unit.Type) || (this.Lots != Unit.Lots));
  }
      
  bool IsChange( void )
  {
    const HISTORY_UNIT Tmp;
    const bool Res = (this != Tmp);
    
    if (Res)
      this = Tmp;
      
    return(Res);
  }
};

// Возвращает true только в случае, если с последнего вызова произошли торговые изменения
bool IsChange( void )
{
  static HISTORY_UNIT History[];  

  const int Total = OrdersTotal();  
  bool Res = (ArraySize(History) != Total);

  for (int i = 0, j = Res ? ArrayResize(History, 0, Total) : 0; i < Total; i++)      
    if (OrderSelect(i, SELECT_BY_POS))
    {
      if (Res || (Res = History[j].IsChange()))
        ArrayResize(History, j + 1, Total);
      
      j++;
    }
  
  return(Res);
}

这个版本对VPS上的MT5特别有意义,因为MT5在历史上的工作非常缓慢,而且计算成本很高。

显然,任何OOP都可以用程序化的方式重写。但我感兴趣的是这种做法。所以我把上面的小代码,其中的OOP也用到了最小。

那么,在这个例子中,与OOP相比,程序式有多好/多方便/多可读/多正确呢?好了,不说几页了,只想比较一下短的源代码程序化与OOP。我请OOP的对手展示一个大师级的作品。这不是可怕的MT5,而是古老的MT4。

 
Vladimir Pastushak:
请清理这个主题的水灾,只留下Alexey Volchanskiy的 教育帖子

很晚了)))),特别是我只有在这个周末才能抽出时间,突然发现非常忙。

本周末将做一些研究,也许还有一些视频。

 
Vladimir Pastushak:
请清理该主题的水灾,只留下Alexey Volchanskiy的 教育性帖子。

弗拉基米尔,如果你这么多年都没学会,现在开始就太晚了;)。

 
fxsaber:

显然,静态和常量(这不是OOP)是不需要的。

至于OOP,非常有趣的是,下面这个具有广泛实际应用(根本不是抽象的)的功能在程序式中会是什么样子?

很明显,任何OOP都可以用程序化的方式重写。但我对实践感兴趣。所以我把上面的小代码,其中的OOP也用到了最小。

那么,在这个例子中,与OOP相比,程序式有多好/多方便/多可读/多正确呢?好了,不说几页了,只想比较一下短的源代码程序化与OOP。我要求OOP的对手展示一个大师级的作品。这不是可怕的MT5,而是古老的MT4。

即使在这个简单的例子中,你也变得过于复杂了。重写OOP总是比理解别人的代码更容易,....你想做什么,至少要用普通人的语言告诉我?找出订单历史 中的变化是什么?
 
Vasiliy Sokolov:

弗拉基米尔,如果这么多年来他们还没有学会,我想现在开始已经太晚了;)


我可以问他们 是谁 他们还没有学到 什么吗?版主没有学会打扫或其他东西)。

ZS:顺便说一下,在整个线程中没有看到一个希望涉及任何话题的人,一如既往地咬文嚼字。所以我决定在YouTube上录制视频,从头开始介绍OOP的工作原理,至少会有一些用处。总之,过一段时间,该分支将在 branch_sucker 中结束。