3

假设我有两个班级,A 和 B:

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 ),那么一切都很酷,但是我必须强制a转换B*为丑陋的。我不能模板化类型定义,那么有没有一种很好的方法呢?

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 回答
0

这闻起来像虚拟功能工作。

于 2013-03-22T17:27:50.520 回答