0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MQL5はclassの継承とinterfaceの実装が一緒くたなのは勘弁して欲しい (オブザーバーパターンの迂遠な一例)

Posted at

欲にまかせてMT5用のEA作成をしてるのですが、良くある(だろう)インターフェースを実装する形でのオブザーバーパターンなコードを書いたら、コンパイラに怒られました。

コンパイラに怒られる例
class CAnyEvent { /*色々と*/ };

interface IAnyEventListener {
  public:
    void onAnyEvent(const CAnyEvent&);
};

class CBase1 { /*なんやかんや*/ };
class CDerivesAndImplements : public CBase1, IAnyEventListener { /* <-多重継承禁止に引っかかる*/
  public:
    void onAnyEvent(const CAnyEvent&)override;
};

まあ怒られますよね。'implements'てのが無いんだから。
それがinterfaceであるなら、クラスの多重継承禁止の対象にはしないというようにしてくれるコンパイラになってくれんかな、とか思いますが、現になってないんだから仕方がない。

「どうしたもんだか」と悩んだ末に、ひとまずやってみて、一応望んだ通りに動作してくれたのは以下のコード。(CAnyEvent と IAnyEventListener は省略)

結局こうした

// IAnyEventListenerを実装するクラス
// これを一段かませて、実際のリスナーの仕事をするメソッドを呼び出す
template <typename OUTER>
class CAnyEventListener : public IAnyEventListener {
  public:
    CAnyEventListener(OUTER *o) : outer(o) {}
    void onAnyEvent(const CAnyEvent &evt)override {
        outer.onAnyEvent(evt);
    };
  private:
    OUTER *outer;
};

class CAnyEventSource {
  public:
    void addListener(IAnyEventListener*);
};

class CBase1 { /*なんやかんや*/ };

class CListener1 : public CBase1 /*implements IAnyEventListener <-これが出来れば問題無かったのだけど*/ {
  public:
    // コンストラクタで、
    // IAnyEventListener を実装したリスナーオブジェクトに、
    // 自身の存在をセットしておき、イベント発生時には
    // 自身のonAnyEventを呼んでもらう
    CListener1() : anyEvtListener(GetPointer(this)) {}

    // イベントソースにリスナーオブジェクトをセットする
    // (自身をセットするのではない)
    void setAnyEventSource(CAnyEventSource &src) {
        src.addListener(GetPointer(anyEvtListener));
    }

    // 実際にリスナーとしての作業をするメソッド
    void onAnyEvent(const CAnyEvent &evt) {
        /* ........ */
    }

  private:
    // IAnyEventListenerインターフェースを実装したリスナーオブジェクト
    CAnyEventListener<CListener1> anyEvtListener;
};

という感じで、いちおう機能するものにはなりました。
しかし回りくどい。

なんか良い手は無いでしょうかね。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?