指向成员函数的指针执行虚拟调度?

最近我尝试运行以下代码。

#include <iostream>

class Base
{
public:
    virtual void func()
    {
        std::cout<<"Base called"<<std::endl;
    }
};

class Derived: public Base
{
public:
    virtual void func()  override
    {
        std::cout<<"Derived called"<<std::endl;
    }
};

int main()
{
    void (Base::*func_ptr)()=&Base::func; //Yes, the syntax is very beautiful.
    Base* bptr=new Derived();
    (bptr->*func_ptr)();
}

我的预期输出是Base called. 然而,输出是

Derived called

这让我感到惊讶,因为根据我的理解,func_ptr应该只能看到Base成员(因为据我所知,func_ptr不是通过 访问成员函数_vptr,而是访问函数地址本身。

我想知道,在这种情况下虚拟调度是如何发生的(如何访问虚拟表),以及这种行为在 C++ 标准中定义的位置(我搜索过但找不到任何东西)?

回答

参考[expr.call],特别是这里

无论是通过指针调用函数还是通过类成员访问调用函数都是一样的(ref);为虚函数调用的实际函数最终取决于它被调用的对象的实际类型

[class.virtual]下标准中的一些(非规范性)注释大致相同:


如果你想知道虚函数调度是如何发生的,你需要寻找一个具体的实现,因为如何不是标准化的。

(我真的很喜欢这篇文章虚拟表的基本概览,它展示了一种可以使用 C 实现它的可能方法)


以上是指向成员函数的指针执行虚拟调度?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>