汎用クラスライブラリ - バグ、説明、質問、使用上の特徴、提案 - ページ 21

 
fxsaber

IEqualityComparableを起動する代わりに、必要な型に対してGetHashCodeをオーバーロードすればよいのです。

このような場合、末端は非常に遠く、エラーの可能性はライブラリの深部のどこかに現れます。 そして、ある関数が見つからないのはなぜか、それは誰のせいかを推測します。 そして、必要なすべての関数がオブジェクトにすでに定義されていることをあらかじめ保証するのがインターフェースです。

 
アレクセイ・ナヴォイコフ

この場合、末端は非常に遠くまで行き、起こりうるエラーはライブラリの深部のどこかで発生します。 そして、ある関数が見つからないのはなぜか、誰のせいかを推測します。 そして、インタフェースは、必要なすべての関数がすでにオブジェクトに定義されていることをあらかじめ保証しています。

MqlTickの 例を示してください。

 
アレクセイ・ナヴォイコフ

そして、インタフェースは、必要な機能がすべてオブジェクトにすでに定義されていることをあらかじめ保証するものである。

しかし、これらのクラスは普遍的なものであり、すべてのタイプですぐに動作する必要があります。

 
fxsaber

MqlTickの 例を示してください。

class CMqlTick : public IEqualityComparable<CMqlTick*>
{
 public: 
   MqlTick _tick;
   bool    Equals(CMqlTick* obj) { return obj!=NULL && obj._tick.time==_tick.time; }
   int     HashCode(void)        { return _tick.time; }
};
もちろん、授業を入れなければならないコストや、ポインターチェックもあります。
 
アレクセイ・ナヴォイコフ
ここにはもちろん、クラス+ポインターチェックにかける費用が発生します。

ありがとうございます。しかし、この方法の利点が実際にどのようなものなのかがわかりませんね?

SBでは、次のようなコードになっています。

//+------------------------------------------------------------------+
//| Class CKeyValuePair<TKey, TValue>.                               |
//| Usage: Defines a key/value pair that can be set or retrieved.    |
//+------------------------------------------------------------------+
template<typename TKey,typename TValue>
class CKeyValuePair: public IComparable<CKeyValuePair<TKey,TValue>*>
  {
protected:
   TKey              m_key;
   TValue            m_value;

public:
                     CKeyValuePair(void)                                              {   }
                     CKeyValuePair(TKey key,TValue value): m_key(key), m_value(value) {   }
                    ~CKeyValuePair(void)                                              {   }
   //--- methods to access protected data
   TKey              Key(void)           { return(m_key);   }
   void              Key(TKey key)       { m_key=key;       }
   TValue            Value(void)         { return(m_value); }
   void              Value(TValue value) { m_value=value;   }
   //--- method to create clone of current instance
   CKeyValuePair<TKey,TValue>*Clone(void) { return new CKeyValuePair<TKey,TValue>(m_key,m_value); }
   //--- method to compare keys
   int               Compare(CKeyValuePair<TKey,TValue>*pair) { return ::Compare(m_key,pair.m_key); }
   //--- method for determining equality
   bool              Equals(CKeyValuePair<TKey,TValue>*pair) { return ::Equals(m_key,pair.m_key); }
   //--- method to calculate hash code   
   int               HashCode(void) { return ::GetHashCode(m_key); }

このGetHashCodeのオーバーロードを回避するためだけのダンスが提案されていることがわかりました。しかし、この場合、その手間をかける価値があるのでしょうか?

 
fxsaber

ありがとうございます。しかし、この方法の利点が実際にどのようなものなのかがわかりませんね?

SBでは、次のようなコードになっています。

このGetHashCodeのオーバーロードを回避するためだけのダンスが提案されていることがわかりました。しかし、この場合、その手間をかける価値があるのでしょうか?

スピードが重要なら、オーバーロードしたほうがいい。

ポイントは、このライブラリが移植された.NETでは、すべての組み込み型がすでに最初からインターフェースを持っていることです。 int、別名Int32はこのように定義されています。

public struct Int32 : IComparable, IFormattable, IConvertible, 
        IComparable<int>, IEquatable<int>

そのため、そこにオーバーロードが発生することはありません。

そして、CKeyValuePairクラス自体も、少し違った形で宣言されることになります。

しかし、この時間を言語の機能 向上に費やした方がいい。 そうすれば、.Netのライブラリを丸ごとコピーして、すべてがうまくいくはずだ。

 
アレクセイ・ナヴォイコフ
ここにはもちろん、授業で入れる費用と、ポインターチェックがあります。
このコードをGetHashCodeオーバーロードに入れると何が問題なのでしょうか? そうすれば、インターフェイスを継承する必要はありません。
 
コンビナート です。
このコードを GetHashCode オーバーロードに押し込むと何が問題なのでしょうか。

もちろん、可能です。しかし、その分、プロセスのコントロールが難しくなります。例えば、GetHashCodeが何種類もあり、それがコード中に散らばっていて、どれがここで呼ばれているのか(どこにあるのか)、わかりにくい場合があります。 例えば、関数を呼ぶ とき、引数は他の型にキャストされます。 C#では、C++と比べてテンプレートの可能性が非常に限られているのはこのためかもしれません。

 
アレクセイ・ナヴォイコフ

もちろん、可能です。しかし、プロセス制御が複雑になってしまう。

C++では、このインタフェースは不要で、通常の対話は<演算子の単純なオーバーロードで実現され、この演算子はCLASSの外部で定義することができる。

しかし、演算子<をクラスの外でオーバーロードするためには、ネイティブのサポートが必要です。

しかし、構造体を埋め込む場合は、GetHashCodeをオーバーロードする以外に方法がありません。 構造体からの継承は、標準関数を使って手動で構造体をユーザ継承にキャストしなければならないので、すべてが意図通りに動作するようになります。
 
コンビナート です。

構造体からの継承は、標準的な関数を使用する際に、すべてを意図したとおりに動作させるために、手動で構造体をカスタム継承者にキャストすることを余儀なくされるため、松葉杖の解決策となります。

どうやら継承のことではなく、構造体の上にクラスからラップすることを指しているのでしょうか?

実は、この「強制」もMQLの欠点で、キャスト演算子はオーバーロードできないので、そうしないとクラスが暗黙のうちに構造体にキャストされてしまうのです。

しかし、誰も気にせず......開発はもう2年も停滞しており、改善や革新もない。

ここでは開発者自身がマルチインターフェイスの不足などに文句を言いながら、サボテンを食べ続けているが)。