通过指向派生类的函数调用基本虚方法

Ego*_*yak 6 c++ polymorphism inheritance function-pointers

我需要通过指针从派生类调用基本方法A :: foo().

#include <iostream>
struct A{
    virtual void foo() { std::cout << "A::foo()" << std::endl; }
};

struct B:A{
    virtual void foo() { std::cout << "B::foo()" << std::endl; }
    void callBase(void (A::*f)()){
        (this->*f)();
    }
};

int main(){
    B* p=new B();
    p->callBase(&A::foo);
}
Run Code Online (Sandbox Code Playgroud)

此代码输出"B :: foo".是否可以通过指向方法的方法调用A :: foo()?

Rad*_*dek 1

好吧,您可以使用一些技巧来覆盖 的值来执行类似的操作this。不过,您可能永远不应该尝试这样做,因为vtable指针并不意味着要手动修改。

为了执行您所描述的操作,我们需要指向 A 的指针vtable。我们的对象p只有指向 B 的指针vtable,因此我们需要将第二个指针存储在 A 的构造函数内的字段中。

这是代码:

#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);
}
Run Code Online (Sandbox Code Playgroud)

输出:

A::foo()

Process finished with exit code 0
Run Code Online (Sandbox Code Playgroud)