指向虚函数的成员函数指针

use*_*729 6 c++

有关虚拟成员函数与非虚拟函数的 ptr 的信息如何编码在函数指针内。显然,这取决于编译器,但我想了解用于编码此信息的技术。

#include <cassert>

struct X {
    virtual void f() {
    }
    void f1() {        
    }    
};

struct Y : X {
    void f() {
        assert(0); // does trigger
    }
};

int main() {
    auto ptr = &X::f;
    X *p = new Y();
    (p->*ptr)();   
}
Run Code Online (Sandbox Code Playgroud)

Sam*_*hik 7

非虚拟类方法基本上是一个普通函数,因此指向非虚拟类方法的指针在功能上等同于普通函数指针,即函数的地址。

每个非静态类方法,无论是否为虚拟方法,都会接收一个内部指针。你知道它是“ this”。这通常是一个附加的隐藏函数参数。

每个具有虚拟继承的类都有一个隐藏的内部指针作为其类成员之一。它由编译器生成,当创建类的实例时,编译器会自动生成适当的代码来初始化它。该指针指向编译器生成的元数据,其中记录了指向实例化类的元数据的指针以及该类实例的所有真正重写的虚拟函数是什么。

指向虚拟类方法的指针是一个函数的地址,该函数深入this,并使用 的this虚拟函数分派元数据来查找实际的实例化类,然后使用指向虚拟类元数据的隐藏指针来查找适当的虚拟函数重写,对于这个对象,然后(经过几个记账过程)跳转到适当的、真实的、虚拟的函数。

因此,虚拟函数的地址通常也是函数的地址,只不过它不是任何特定的虚拟函数,而是编译器生成的函数,该函数计算出它被调用的“真实”对象及其适当的重写虚函数。

这是典型编译器实现的概括总结。一些细节已被省略。不同编译器之间存在细微的差异。