ラウンジでPLOについて語る - ページ 6

 
George Merts:

これ(およびアンダースコアで始まるすべて)は、クラスの保護された関数である。

まあ、ひとつに統合されたわけですからねー。

Compare()という関数が1つだけありますが、渡されたキーで比較を実行する必要があります。これに対応して、特定のプロテクトされた関数を一つ選択する。そのため、ユーザーがアクセスできないように保護(プロテクト)されています。Compare()からしか呼び出されないので、下線で表示されているのです。

アンダースコアで始まる関数は、ユーザーから呼び出されることを想定しておらず、クラス内の特定のタスクにのみ使用されます。アクセスは制限されています。

しかし、クラシックですべてを行う方がはるかに簡単なのに、なぜそんなサーカスのような芸当をするのでしょう。ラッパー関数や中括弧を使って、ネストした変数や関数を隠し、アクセスできないようにすれば、満足できるはずです。こんなプロテクトで自分も他人も混乱させるだけなのに・・・。

 
Andrei:

しかし、クラシックを使えばもっと簡単にできるのに、なぜそんなサーカスのような芸当をするのでしょう。ラッパー関数や中括弧を使って、ネストした変数や関数を隠し、アクセスできないようにすれば、満足できるはずです。こんなプロテクスで自分や他人を混乱させるだけだ...。

意味がわからない...。Protected は、関数のアクセス修飾子です。つまり、あるクラスかその子孫の関数からしかアクセスできないプロテクタ関数が使われているのです。また、アンダースコアは、個人的には、それを使うときに考慮しなければならない暗黙の前提があることを意味します。

Dennis Kirichenkoが 正しく指摘したように、1つのCompare()関数ですべてを記述することができます。でも、そうすると画面が2ダースになって、目を通すのも非現実的になるし、改造も今より大変になりますよね。

キーセレクタだけをCompare()関数に残し、特定のキーに対する比較を行うコードは別の関数に配置しました。これらの関数は非常に文脈に依存するため、クラスの protected セクションで宣言し、そのクラスまたは子孫の別の関数から排他的にアクセスできるようにしています。 また、これらの関数が別の関数内で特定の狭いタスクを実行することを目的としていることを忘れないように、下線を付けて開始します。将来、このような関数に出会ったら、その関数を呼び出すときに考慮しなければならない暗黙の前提があることをすぐに理解できるだろう。

あなた(以下、「あなた」とします)は、アクセス修飾 子が何なのか、なぜ必要なのか、よく分かっていないようですね。

 
George Merts:

意味がわからない...。Protected は、関数のアクセス修飾子です。つまり、あるクラスかその子孫の関数からしかアクセスできないプロテクタ関数が使われているのです。さらに、私個人としては、アンダースコアの記号は、それを使うときに考慮すべき暗黙の前提があることを意味します。

さて、OOPを使わずに、古典的な方法で関数へのアクセスを制限することができます。
 
Artyom Trishkin:

でも、個人的な侮辱はダメですよ...。

アレクセイ・ヴォルチャンスキーの 教育的な投稿だけを残して、スレッドを洪水から掃除してください。
 
Andrei:
さて、OOPを使わずに、古典的な方法で関数へのアクセスを制限することができます。

どのように?

将来、コードを修正するときに、ある関数を「どこでも」使えるようにすることです。public-protected-private修飾子を用いてクラス空間への アクセスをOOP的に制限することなく行うにはどうしたらよいでしょうか。

 

どうやらstaticとconst(これは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);
}

MT5はHistoryの動作が非常に遅く、計算コストが高いため、このバージョンは特にVPS上のMT5と関係があります。

もちろん、どんなOOPでも手続き型に書き換えることは可能です。しかし、私が興味を持ったのは、その実践です。そこで、上記のような小さなコードで、OOPが最小限しか使われていないものを取り上げました。

では、この例でOOPと比較して手続き型はどれだけすっきりしているか/便利か/読みやすいか/正しいか?さて、数ページにわたって話をするわけではありませんが、短いソースコードの手続き型とOOPを比較するだけです。OOPの対戦相手には、名人芸を見せてもらう。これは、恐るべきMT5ではなく、古き良きMT4です。

 
Vladimir Pastushak:
アレクセイ・ボルチャンスキーの 教育的な投稿だけを残して、このスレッドを洪水から掃除してください。

特に今週末しか時間が取れないので、急に忙しくなってしまいました。

今週末には、ビデオも交えて勉強するつもりです。

 
Vladimir Pastushak:
アレクセイ・ヴォルチャンスキーの 教育的な投稿だけを残して、スレッドを洪水から掃除してください。

ウラジミール、ずっと習ってないなら、今からでも遅くないよ;)。

 
fxsaber:

どうやらstaticとconst(これはOOPではない)は必要ないようです。

OOPに関しては、次のような実用性の高い(抽象的でない)関数が手続き型になるとどうなるのか、非常に興味深いですね。

もちろん、どんなOOPも手続き型に書き換えることは可能です。でも、練習には興味があります。そこで、OOPも最低限使われている上記のような小さなコードをとってみました。

では、この例で、手続き型はOOPと比較して、どれだけすっきりしているか/便利か/読みやすいか/正しいか?さて、数ページにわたって話をするわけではありませんが、短いソースコードの手続き型とOOPを比較するだけです。OOPの対戦相手には、名人芸を見せてもらう。これは、恐るべきMT5ではなく、古き良きMT4です。

この単純な例でも複雑になりすぎだよ。他人のコードを理解するよりも、OOPを書き直す方が簡単なのはいつものことですが......。どうしたいのか、せめて人間の言葉でわかりやすく教えてください。受注 履歴の推移を確認する
 
Vasiliy Sokolov:

ウラジミール、もしこの何年もの間、彼らがまだ学んでいないのなら、始めるには遅すぎると思います;)


彼らが誰で、 何を学んで いないのかを聞いてもいいのでしょうか?モデレーターは掃除とか習ってないし )。

ZS: ところで、このスレッドでは、どのトピックについても、報道を望む声はひとつもなく、いつものように険悪な雰囲気でした。そこで、せめて何かの役に立てばと思い、OOPの仕組みを一からYouTubeで動画撮影することにしました。とにかく、しばらくするとブランチがbranch_suckerで終わってしまうのです。