Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to register a derived class member function pointer with a base class

As opposed to virtual member functions, I need a solution where a function implemented at each level class derivation can be registered for later call by the base class. ( Not just the most derived implementation)

To do this, I was thinking on providing a mechanism for derived classes to register their function with the base class such as during the derived class constructor.

I'm having trouble with the member function pointer argument though. I was thinking that Derived is derived from Base, the this pointer should be automatically casted.

Can this be done close to what I am trying or do I need to use static member functions, void *, and static_cast?

class Base
{
protected:
    typedef void (Base::*PrepFn)( int n );
    void registerPrepFn( PrepFn fn ) {};
}

class Derived : public Base
{
    Derived() {
        registerPrepFn( &Derived::derivedPrepFn );
    };

    void derivedPrepFn( int n ) {};

}

Compiler error:

error: no matching function for call to 'Derived::registerPrepFn(void (Derived::*)(int))'
note: candidates are:                 'void Base::registerPrepFn(void (Base::*)(int))'
like image 497
NoahR Avatar asked Apr 08 '12 21:04

NoahR


1 Answers

If all you need is beating the error message, then casting will do:

class Derived : public Base
{
    Derived() {
        registerPrepFn( static_cast<PrepFn>(&Derived::derivedPrepFn) );
    };

    void derivedPrepFn( int n ) {};

}

Call it normally with a Base* p (provided it actually points to a Derived): (p->*registered)(0)

See http://ideone.com/BB9oy for a working example.

like image 146
jpalecek Avatar answered Oct 13 '22 01:10

jpalecek