Suppose I have two classes, A and B:
class A
{
public:
typedef void (*Handler)( A * a );
Handler handler;
void foo() ( handler( this ); }
};
class B : public A
{
};
Suppose I have a function
void bar( B * b );
Can I then go
B b;
b.handler = bar;???
If I declare void bar( A * a ) then all is cool, but then I have to cast a to a B* which is ugly. I can't template a typedef, so is there a nice way of doing this?
No, there isn't.
You're violating LSP: b.handler() can't be called with any random A*, while the base class promisses it can.
B b;
b.handler = bar; // This doesn't compile!
A a2;
b.handler(&a2); // As this would call bar(B*) with an A*
It is possible to have a different type in cases like this, but only when arguments are contra-variant and return values co-variant.
This is the solution mentioned by cdhowie. You can define an abstract base class:
template<typename T>
class AbstractA {
typedef void (*Handler)( T * a );
Handler handler;
void foo() ( handler( (T*) this ); }
};
And then implement child classes like this:
class A : public AbstractA<A> {
//...
};
class B : public AbstractA<B> {
//...
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With