Well, you can do something similar using some tricks with overwriting the value of this. You probably should never try to do that though, vtable pointers aren't meant to be modified by hand.
To do what you described, we need to have the pointer to A's vtable. Our object p has only pointer to B's vtable, so we need to store second pointer in a field within A's constructor.
Here is the code:
#include <iostream>
struct A{
virtual void foo() { std::cout << "A::foo()" << std::endl; }
int *a_vtable_ptr;
// First, save value of A's vtable pointer in a separate variable.
A() { a_vtable_ptr = *(int**)this; }
};
struct B:A{
virtual void foo() { std::cout << "B::foo()" << std::endl; }
void callBase(void (A::*f)()){
int *my_vtable_ptr = *(int**)this;
// Then modify vtable pointer of given object to one that corresponds to class A.
*(int**)this = a_vtable_ptr;
(this->*f)(); // Call the method as usual.
// Restore the original vtable pointer.
*(int**)this = my_vtable_ptr;
}
};
// Function main() is not modified.
int main(){
B* p=new B();
void (A::*f)() = &A::foo;
p->callBase(f);
}
Output:
A::foo()
Process finished with exit code 0
p->A::foo();but not through a pointer to member function (which I guess is the point of virtual functions).barthat does the work, and havefoodelegate tobar,callBasethen callsbar. This is more logical since polymorphism meansBshould always call its ownfooA* a = new B; auto p = &A::foo; (a->*p)();