エラー、バグ、質問 - ページ 1356

 
Vasiliy Sokolov:
とてもクールで、何より思想的に正しい。両手を挙げて賛成!
そうすれば、思想的に正しい
class A { public:
        bool operator !=( A* ) {}
        bool operator  <( A* ) {}
};
void f()
{
    A *a1, *a2;
    a1 != a2; //здесь простое сравнение указателей вместо вызова operator !=()
    a1 <  a2; //здесь вызывается operator <()
}
operator!=()が呼び出され、現在のようなポインタの等価比較は行われないでしょう。また,ポインタの比較は ::GetPointer(...) のような特別な関数で行うことができます.

しかし、これは大きな不便をもたらし、利点はイデオロギー的な正しさだけであるという単純な理由で行われることはない

 
久しぶりの更新:MetaTrader5 build 1159 (MetaQuotes-Demoに接続)。コマンドコンパイラがビルド1162をロード
 
Vasiliy Sokolov:

それから、文字列は特定の数字の集合でもあります。そして、絵は数字でもあり、チップ上の電気パルスでもある...。

一般的には、電気工学を勉強する、同僚。

ここでは、C++のポインタとMQL/C#や他のいくつかの言語のディスクリプタを比較します。

課題 - 仲間とライブチャットをしたい。

1.ポイント通り、家屋番号、アパートがわかる。私たちは、アドレスに行き、友人を起こし、泡を取得し、彼は興奮してチャットしている))。

2.ディスクリプタ。正確な住所はわからない。誰も家に入ることはできない。たとえば、FSBの建物であるとか。家の中にチェックポイントがあり、友人の名前で住所を言うことを拒否し(記述子によって)、家の中に入れることを拒否する(アドレス空間において)。警備員が仲間を呼び、出てくるよう求める。彼が出てきて、あなたが元気よく泡を出すと、彼は「なんだお前!!!すぐにしまえ!!」とヒスを起こします。未開封のボトルを手に家路につくと、説明文は道しるべとなる能力と引き換えに、安心感を与えてくれるのだと、しみじみと実感する。

 
Vasiliy Sokolov:

一般的には、電気工学を勉強する、同僚。

他に反論はないのか?
 
A100:
他に反論はないのか?
あなたはどうですか?
 
A100:
ポインタを明示的に数値に変換しているコードスニペットがありますが(外部の書き込み/読み取りシステムとの連動や、エラー解析やデバッグのため)、これが禁止されると柔軟性が低下し、やり直しが必要になります。
面白い議論ですね、考えるのに時間がかかります。ご要望をお聞かせいただければ、詳細を検討させていただきます。
 

ところで、MQLに*と &の 演算子を導入して、前者ではオブジェクトへの明示的なアクセスを可能にし、後者では(面倒なGetPointerの 代わりに)オブジェクトポインタを 取るというのはどうでしょう。 アスタリスクは必須で、言語上何とも代えがたいものです。これがないと、上記A100のような、オブジェクトそのものではなく、何らかのポインタ動作が行われるような状況を制御することができません。 個人的には、これは常に問題で、常に警戒していないと、いたるところでA.operator=(B)、A.operator!=(B)と指定しなければならず、すなわち簡潔さが失われ、演算子のオーバーロードは実際には無意味になります。

以前にも一度、この問題を提起したのですが、話題が滞ってしまいました。 ようやくこの問題を終わらせることができました。

 

extern変数について質問です。

プログラム実行 中にextern変数が変化しても、timeframeを変更すると、再びプロパティウィンドウで設定した値を取るという事態に直面しました。例えば、開始前にTradeEnableをEnableAllに設定し、プログラム実行中にEnableBuyに変更した場合、チャートが他のタイムフレームに変わると、値はEnableAllに戻されます。タイマーイベントで定義した値をCommentで出力すると、エラーになることはない。

enum ETradeEnable {EnableAll, EnableBuy, EnableSell, DisableAll};
extern ETradeEnable TradeEnable = EnableAll;

TradeEnable変数は、チャートの反転の影響を受けません。マニュアルを読む -入力変数と異なり、外部変数の値はプログラム実行中に変更 することができます。

OnDeinitとOnInitはそのように設定されています。

質問:理解できないことがあります またはTradeEnableの変更はランタイムエラーですか?

int LastDeinitReason = 0;

void OnDeinit(const int reason)
{
    LastDeinitReason = reason;
    if(reason==REASON_CHARTCHANGE || reason==REASON_TEMPLATE || reason==REASON_PARAMETERS)
        return;
    EventKillTimer();
// далее код при завершении работы советника
}

int OnInit()
{
    if(LastDeinitReason==REASON_CHARTCHANGE || LastDeinitReason==REASON_TEMPLATE)
    {
        LastDeinitReason = 0;
        return(INIT_SUCCEEDED);
    }
    if(LastDeinitReason==REASON_PARAMETERS)
    {
        SetParams();
        return(INIT_SUCCEEDED);                              
    }
// далее код инициализации при запуске
}
 
Alexey Navoykov:

最後にこの問題を終わらせましょう。

そこで2つの演算子(==と!=)が犠牲になり、他のすべての演算子が維持されている。

パターンで出口を見出す。

template<typename T1, typename T2>
bool IsEqualPointer( const T1 *t1, const T2 *t2 )
{
    return ( ulong(t1) == ulong(t2) );
}

operator==(!=) が定義されている場合は、それが呼び出される。定義されていない場合、ポインタは等価に比較される。また、operator==(!=)が定義されており、ポインタの等価性を比較する必要がある場合、指定されたテンプレートによって行うことができます。

既存のシステムに対する変更は最小限で、主なものは、operator==(!=)のオーバーロードをせずに単にポインタを等価比較する人たちに影響を与えないということです。

 
A100:

そこで2つの演算子(==と!=)が犠牲になり、他のすべての演算子が維持されている。

パターンで出口を見出す。

operator==(!=) が定義されている場合は、それが呼び出される。定義されていない場合、ポインタは等価に比較される。また、operator==(!=)が定義されていて、ポインタを等価に比較する必要がある場合は、指定されたテンプレートによって行うことができます。

既存のシステムの変更は最小限で、主なものは、operator==(!=)のオーバーロードをせずに単にポインタを比較する人に影響を与えないということです。

もちろん、比較と代入を別々の関数で行うこともできますが、何の意味があるのでしょうか?要は、開発者を説得して、正常なソリューションを作ってもらうことです。