zam664
zam664

Reputation: 767

Void Pointers with Inherited Classes

I have a class, A, which requires static event handlers. I needed the static event handlers because an interrupt is calling the event handler.

class A {
private:
    static void (*fn1)();

public:
    A();
    static void setFn1(void (*function)(void));
    static void onEvent();
};

A::A() { }

void A::setFn1(void (*function)(void)) {
    fn1 = function;
}

void A::onEvent() {
    A::fn1();
}

I want to inherit A based upon the application and create the event handler logic in the child, using fn2 here.

class B : public A{
public:
    B();
    void fn2();
};

B::B() {
    A::setFn1(&fn2);
}

void B::fn2() {...}

When I call: A::setFn1(&fn2) I get the following compiler error.

#169 argument of type "void (B::)()" is incompatible with parameter of type "void ()()

My mind is all loopy with these void-pointers and I do not know if I am even using the proper design anymore. The A class contains all my utility methods. The B class contains my application specific functionality.

Upvotes: 1

Views: 722

Answers (2)

A non-static member function is not a free function, the types differ. You cannot use a non-static member function as if it was a pointer to a function:

struct test {
   void foo();
   static void bar();
};

&test::foo --> void (test::*)()
&test::bar --> void (*)()

I won't go in as much as recommending changing the function to be static as I don't find the current design particularly useful. But you can take this and try to rethink a design that will make more sense. (A single callback function for all the process? Why inheritance at all? A user-defined constructor that does the same as the compiler generated? In a class that should not be instantiated?...)

Upvotes: 3

Andy Prowl
Andy Prowl

Reputation: 126432

When I call: A::setFn1(&fn2) I get the following compiler error.

fn2 is a member function of a B, so you have to qualify its name:

A::setFn1(&B::fn2)
//         ^^^

Moreover, fn2 should be static, because non-static member functions actually work on an implicit this pointer, so they are accepting an argument:

class B : public A{
public:
    B();
    static void fn2();
//  ^^^^^^
};

With these two changes, your program should compile.

Upvotes: 2

Related Questions