Search code examples
c++functionpointersvirtual

Pointer to virtual function


So I'm in a bit of a dilemma right now. I want to make a function pointer, but I want to make it to a virtual function. Not necessarily the virtual function itself, but the derived one. I tried just making the pointer, but the function needs to be static. When I try to make a static virtual function, the compiler yells at me. I also don't want to make the function pointer class specific so conceivably other classes could use the pointer. Here is what I mean in pseudocode:

class C
{
public:
    virtual void something();
};

class B : public C
{
public:
    void something();
};

class D
{
public:
    void something();
};


int main()
{
    void(*pointer)();
    B b;
    D d;
    pointer = b.something.
    pointer();
    pointer = d.something;
    pointer()
}

Something is not a static method but I want the pointer to be able to point to it. Also the pointer can point to other class methods that are also not static. Is there anything I can do with this?

EDIT I finally was able to figure out how to do this. I had to use std::function. This should also work for just regular member functions, not necessarily virtual one. Here is what it would look like:

class A
{
 public:
virtual void something(int i);
};
class B
{
virtual void somethingElse(int i);
}
//This isn't needed, it just saves typing if you have multiple pointers
typedef std::function<void(int)> functionType
functionType* pointer;

int main()
{
 B b;
 A a;
 pointer = std::bind(&A::something,&a,std::placeholders::_1);
 pointer(1)
 pointer = std::bind(&B::somethingElse,&b,std::placeholders::_1);
 pointer(4)
}

Theres quite a bit on the internet on std::bind, so if you're curious you can read about it. I found this particularly helpful, as it has a very similar solution to what I have. std::function to member function Thanks to all who have helped.


Solution

  • You won't be able to assign a pointer-to-member function to a normal function pointer: function pointers don't take any additional arguments while member function take an implicit this pointer as argument. You might want to use a std::function<...>, though:

    std::function<void()> pointer;
    B b;
    pointer = std::bind(&C::something, &b);
    pointer();
    D d;
    pointer = std::bind(&c::something, &d);
    pointer();
    

    You could avoid using std::function<...> if you pass a pointer to the object and a suitable member function pointer around and there is common base class (while the code above works with the missing inheritance, the code below requires that C is a base of D):

    void (C::*member)() = &C::something;
    C* c = &b;
    (c->*member)(); // calls b.something() using B::something()
    c = &d;
    (c->*member)(); // calls d.something() using D::something()
    

    C++ doesn't have a notation using &object.member to get the address of a readily bound member function. ... and, even if it did, its type wouldn't be void(*)() either.