Reputation: 1286
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?
Upvotes: 3
Views: 144
Reputation: 11482
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> {
//...
};
Upvotes: 1
Reputation: 6875
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.
Upvotes: 4