Julian Gold
Julian Gold

Reputation: 1286

Casting function pointers in C++

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

Answers (3)

JP Cordova
JP Cordova

Reputation: 119

This smell like virtual functions job.

Upvotes: 0

Sebastian Hoffmann
Sebastian Hoffmann

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

Sjoerd
Sjoerd

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

Related Questions