OOP(オブジェクト指向プログラミング)に関する質問 - ページ 6

 
C-4:
動的な型識別が必要な複雑なオブジェクト変換にはポインターは欠かせません。 。

ワシリー、例を挙げてくれ!」。

メモリを確保する必要があり、そのポインタが必要なケースを1つだけ知っています。

ほとんどなくても大丈夫だと思います。手動でのメモリ管理は行わないことが望ましい。これらの問題をすでに処理している標準的なライブラ リが必ずあります。

 
Integer:


それは、何事もできるだけシンプルに行うことです。ただ、物事の真っ只中に入る必要はないんです。シンプルに解決できる問題は、シンプルに解決すべきなのです。


その通りです。そして、ここで重要なのが、クラスを正しく設計することです。そして、そのためには、次のクラス(子孫)がどうなるかを予測することが重要です。

通常、ベースクラスは最低限の機能を持つことが望ましいが、クラス利用のベクトルを設定するような仮想メソッドを多く作ることが望ましい。

MQLの場合、おそらくその逆で、VOLDEMARの ようにベースクラスでより多くの機能を実現します。しかし、狂信的なものはない。


トレードマークのプロパティ(POINT、STOPLEVELなど)があります。MarketInfo() の場合はMODE_XXX)。cSymbol クラスに押し込んだ方がいいんじゃない?


注文のプロパティ(始値、タイプ、ロットなど)があります。OrderXXX())。例えば、別のcOrder クラスに入れた方が良いだろう。

注文を部分的に閉じることができることを覚えていれば、BaseLot フィールドもクラスに割り当てる必要があります (どの部分のロットがすでに閉じられているかを知るため)、など。


私にとっては)スケジュール - 注文を開くと閉じることができる指定された期間(日によって)、我々は唯一のクローズ(我々はすでにブレークイーブンであれば末尾)、我々は全く動作しませんし、すべてのオープン、未開封の注文を削除する期間です。

ギャップについて、そして多くの(すべてではない)証券会社での取引の最後の時間に取引条件を変更することがあり、多くの証券会社が取引金属で毎取引日の休憩を持っていることを忘れないでください。


そして最後に、EAというものがあります。これは、特定のシンボル、特定のスケジュール、特定の注文リスト、独自の計算用データで動作する特定のアルゴリズムです。

cSymbol クラスのオブジェクトと cOrder クラスのオブジェクトの配列を含むcExpert クラスを作成します。この基本的なcExpertは cOrder オブジェクトのプロパティを更新する関数、オーダー処理の関数、エラー処理、統計などを含むことになる。

個人的には、AccountFreeMargin() の%%でロットを計算する、注文ごとにユニークなマジックを生成する(特定の注文にリバースオーダーをかけやすい)、リバースオーダーをかける機能などが便利だと思っています。

そして、ここからcExpertが 独自の追加データセットと、マーケットで何をすべきかを決定する機能(オープン/カンパニー/クローズオーダー)を降臨させることができるのです。

すなわち、トレーディング戦略の実行です。そして、いわゆる「○○戦略EA」になります。


しかし、すべての基本 機能は、ベースとなるcExpert クラス内にあります。子クラスには、取引戦略のアルゴリズムが格納されます。

まあ、(ソースコードがなく、基本的なcExpertに詰め込むことができないのであれば)誰かが取引に関する高度なエラー処理や高度な統計情報を追加するかもしれませんね。

なお、EAを簡単に書けるようにするために、時間をかけてクラスを作成しています。実はこれ、Expert Advisorのテンプレートなんです。構造的に完全で、ブラッシュアップされていない(必要なデータがコードと一体になったもの)。


openorders()を超えるラッパー関数の「冗長性」については、個人的には、そのようなラッパーを支持します(特に - 基本関数を呼び出すだけでなく、追加機能を備えている場合)。

例えば,wrapperの呼び出しでSLと TPが ポイントで指定され,それを絶対座標に変換し,さらにオーダーの種類によって加算や減算をしなければならない場合(この場合もoperorders()で変換を行うことができます),そのような変換を行うことができます.

個人的には、OrderSend()の パラメータが正しいかどうかを毎回解析するよりも、BuyStop(...)を 呼び出すコードを理解し、BuyStop() がすべてを正しく行うことを一度チェックする方が簡単だと思います。

PS:土日も含めて大変でしたね。Pavlickさん、 mql5 さん、サンプルコードをありがとうございました。

これらの例を見て、MQLで書かれたプログラミングタスクの領域で、本当にクラスの階層を作る必要があるのだろうか、と考えてみてください。

基本的なもの(「三角形」「四角形」など)をベースにしたクラス群が本当に必要なのでしょうか?

そしてまたインテージの 金言、「藪の 中に入ってはいけない」。

ああ、私が気づかなかったのか、それとも最近例のあるドキュメント セクションが現れたのか。

 
Zhunko:

メモリを確保する必要があり、そのポインタが必要なケースを1つだけ知っています。

ほとんどなくても大丈夫だと思います。手動でのメモリ管理は行わない方がよいでしょう。これらの問題をすでに解決している標準ライブラリが必ずあります。


こんなところでしょうか。


cFather クラスがあり、 int型のGetData() メソッドを持っていて、3が返ってくるとします。そして、GetData() から取得したものを出力するメソッド PrintData()

その子孫であるcChildは GetData() をオーバーライドしており、現在は5を返しています。

cFather 型のオブジェクトをTestObjectと 宣言すると、TestObject.GetData() は常に3を返します。

cFather* TestObject=new cChild1 と宣言すると、cFather と思われるのにTestObject.GetData() は 5 を返します。

これは、cFather クラスの子孫クラスがまだ存在しない場合でも、現在書かれているコードでGetData() メソッドを呼び出すことができるようにするために必要なものです。

つまり、cChild2 クラスが出現して、GetData()が 7を返すと、cFather* Test2=new cChild2 functionTest2.PrintData() の 後に、7が出力されるようになるのです。

もし、「cFather クラスオブジェクトへの参照」パラメータを期待する関数があり、それをGetData() で使用すれば、どの cFather の 子孫に対しても正しいデータを取得することができます。

メソッドバインディングは、newが 呼ばれたときに発生します。もし、参照されていなければ、バインディングはハードになり、すなわち宣言されたクラスのメソッドが呼び出されることになります。

こちらと こちらを ご覧ください

 
EverAlex:

ということのようです。

...

メモリやポインタを確保することなく、基底クラスと派生 クラスの連鎖全体で任意のメソッドにアクセスできる「::」演算子がある。
 
C-4:


あなたのクラスは9割がた冗長です。主な機能は openordersと の2つだけです。 なぜSelやBuy SelStopなどを使っているのですか?実際はすべてOpenordersを呼んでいるだけなのに。さらに、オーダー型はint型として渡されるため、protectedではありません。intの代わりに、独自の列挙型か標準のENUM_ORDER_TYPEを使用したほうがよいでしょう。また、一般に、マジックナンバー "1 "や "2 "などは絶対に使用しない方がよく、列挙のみ使用します。これにより、左のオーダー値を関数に送信することを防ぐことができます。Openordersの機能自体が大きすぎるのです。当然ながら、取引をするブロックと条件を確認するブロックの2つで構成されています。それぞれ独立したプライベートな機能であるべきです。

それは良いスタートですが、まだ学ぶべきことはたくさんあります。チップ関数は、次のように書き換えた方が良いだろう。

メソッドを呼び出す際に、どのような注文 なのか視覚的に確認できるのは便利なのですが......。

比較について、doubleと0を比較することが推奨されない理由を具体的に説明してください。

 
C-4:
動的な型識別が必要な複雑なオブジェクト変換にはポインターは欠かせません。 。

動的型識別の有無は、通常、プロジェクトの クラッチ・アーキテクチャを示します。
 
EAでクラスがグローバルに宣言されている場合(クラスc;)、あるティックで変更された内部クラスオブジェクトの 状態は、次のティックが来たときに保存されるのでしょうか?
 
EverAlex:

ということのようです。


cFather クラスがあり、 int型のGetData() メソッドを持っていて、3が返ってくるとします。そして、GetData() から取得したものを出力するメソッド PrintData()

その子孫であるcChildは GetData() をオーバーライドしており、現在は5を返しています。

cFather 型のオブジェクトをTestObjectと 宣言すると、TestObject.GetData() は常に3を返します。

cFather* TestObject=new cChild1 と宣言すると、cFather と思われるのにTestObject.GetData() は 5 を返します。

これは、cFather クラスの子孫クラスがまだ存在しない場合でも、現在書かれているコードでGetData() メソッドを呼び出すことができるようにするために必要なものです。

つまり、cChild2 クラスが出現して、GetData()が 7を返すと、cFather* Test2=new cChild2 functionTest2.PrintData() の 後に、7が出力されるようになるのです。

もし、「cFather クラスオブジェクトへの参照」パラメータを期待する関数があり、それをGetData() で使用すれば、どの cFather の 子孫に対しても正しいデータを取得することができます。

メソッドバインディングは、newが 呼ばれたときに発生します。もし、参照されていなければ、バインディングはハードになり、すなわち宣言されたクラスのメソッドが呼び出されることになります。

こちらと こちらを ご覧ください

class cFather
{
public:
    int GetData() {return 3;}
};

class cChild : public cFather
{
public:
    int GetData() {return 5;}
};
    
int f(cFather *p) {return p->GetData();}
    
int main()
{
    cChild obj;
    f(&obj);                // вернет 3
    obj.cFather::GetData(); // вернет 3
    
    return 0;
}
 
Pavlick:


もしかしたら、私は無駄に例を書いてしまったかもしれません。MKLでは動作しない。

cChild obj;
f(&obj);                // вернет 3
obj.cFather::GetData(); // вернет 3

H.K.さん、指南役ではなく、棒読みで笑いを取るんですね。

追伸:dllで書くと、普通の言語を学ぶチャンスがあります。

 
Pavlick:


もしかしたら、私は無駄に例を書いてしまったかもしれません。MKLでは動作しない。

H.K.さん、指南役ではなく、棒読みで笑いを取るんですね。

追伸:dllで書くと、普通の言語を学ぶチャンスがあります。


class cFather
  {
public:
   int GetData() {return 3;}
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class cChild : public cFather
  {
public:
   int GetData() {return 5;}
  };

int f(cFather *p) {return p.GetData();}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnStart()
  {
   cChild obj,*ptr=GetPointer(obj);
   f(ptr);                     // вернет 3
   ((cFather *)ptr).GetData(); // вернет 3

   return 0;
  }