通过成员函数指针调用基成员函数实现到虚函数

Call base member function implementation through member function pointer to virtual function

本文关键字:函数 成员 实现 指针 调用      更新时间:2023-10-16

我有一个情况,我想要一个成员函数指针,指向一个避免动态调度的虚函数。 见下文:

struct Base
{
    virtual int Foo() { return -1; }
};
struct Derived : public Base
{
    virtual int Foo() { return -2; }
};
int main()
{
    Base *x = new Derived;
    // Dynamic dispatch goes to most derived class' implementation    
    std::cout << x->Foo() << std::endl;       // Outputs -2
    // Or I can force calling of the base-class implementation:
    std::cout << x->Base::Foo() << std::endl; // Outputs -1
    // Through a Base function pointer, I also get dynamic dispatch
    // (which ordinarily I would want)
    int (Base::*fooPtr)() = &Base::Foo;
    std::cout << (x->*fooPtr)() << std::endl; // Outputs -2
    // Can I force the calling of the base-class implementation
    // through a member function pointer?
    // ...magic foo here...?
    return 0;
}

出于好奇,我想要这样做的原因是因为派生类实现正在使用实用程序类来记忆(在基类实现周围添加缓存)。 实用程序类采用函数指针,但当然,函数指针动态调度到派生最多的类,我得到了无限递归。

是否有一种语法允许我重现x->Base::foo()但通过函数指针可以实现的静态调度行为?

您可以像这样强制切片Base*

std::cout << (static_cast<Base>(*x).*fooPtr)() << std::endl; // Outputs -1

没有具有所需属性的独立"成员函数指针"。最接近绑定成员函数的是闭包:

Base * x = new Derived;
auto f = [x]() { x->Base::Foo(); }
f();

如果你的类Base是一个特殊的、一次性的用例,并且在你的控制之下,你可能应该向它添加某种"接受访问者"函数,这样你就可以动态地传入成员调用者,比如x->accept(foo_caller);等。C++14 中的示例:

struct X
{
    template <typename F>
    auto accept(F && f)
    {
        return [this, &f](auto &&... args) {
            return f(this, std::forward<decltype(args)>(args)...); };
    }
    virtual void foo() const { std::cout << "basen"; }
};

用法:

void call_static_foo(X * p)
{
    p->accept([](X * that){that->X::foo();});
}