3

A と B の 2 つのクラスがあるとします。

class A
{
public:
    typedef void (*Handler)( A * a );

    Handler handler;

    void foo() ( handler( this ); }
};

class B : public A
{
};

関数があるとします

void bar( B * b );

じゃあ行こうかな

B b;
b.handler = bar;???

私が宣言した場合void bar( A * a )、すべてがクールですが、醜いaa にキャストする必要があります。B*typedef をテンプレート化できないので、これを行う良い方法はありますか?

4

3 に答える 3

4

いいえ、ありません。

LSPに違反しています。b.handler()をランダムなA *で呼び出すことはできませんが、基本クラスは呼び出すことができます。

B b;
b.handler = bar; // This doesn't compile!
A a2;
b.handler(&a2); // As this would call bar(B*) with an A*

このような場合に異なるタイプを持つことは可能ですが、引数が逆バリアントであり、戻り値が共バリアントである場合に限ります。

于 2013-03-22T14:29:00.927 に答える
1

これは cdhowie が言及した解決策です。抽象基本クラスを定義できます。

template<typename T>
class AbstractA {
   typedef void (*Handler)( T * a );
   Handler handler;

   void foo() ( handler( (T*) this ); }
};

そして、次のように子クラスを実装します。

class A : public AbstractA<A> {
    //...
};

class B : public AbstractA<B> {
    //...
};
于 2013-03-22T14:33:11.693 に答える