从基类实例获取指向(纯)虚函数的指针

问题描述 投票:3回答:1

我有以下c ++ 11代码,它可以工作,而我本来期望它崩溃甚至不编译。检索指向纯虚拟成员函数的指针应该返回null或无效指针,或者应该被编译器阻止。我想了解它的工作原理。

我知道还有其他(更好的)方法来编写代码,这是理解语法功能的纯粹理论问题。

#include <iostream>
#include <functional>

class Abstract
{
public:
    void foo()
    {
        auto func = std::bind(&Abstract::virtualFoo, this);
        func();
    }

protected:
    virtual void virtualFoo() = 0;
};


class Derived1 : public Abstract
{
private:
    void virtualFoo() override
    {
        std::cout << "I am Derived1\n";
    }
};

class Derived2 : public Abstract
{
private:
    void virtualFoo() override
    {
        std::cout << "I am Derived2\n";
    }
};


int main(int argc, char *argv[])
{
    Abstract * a1 = new Derived1;
    Abstract * a2 = new Derived2;

    a1->foo();
    a2->foo();

    return 0;
}

意图非常清楚,在基类函数foo()中我想得到一个关于派生虚函数的指针。

但是,根据我的理解,它不应该工作,甚至不应该用纯虚函数编译。使用非纯虚函数,它应该执行基类函数。但是,我很惊讶地看到它编译,并产生预期的输出:它打印“我是Derived1”然后“我是Derived2”

&Abstract::virtualFoo如何返回一个有效的指针,甚至不知道指向实际对象的指针,必须访问一个vtable ???

在线C ++链接:https://onlinegdb.com/SJfku8rvV

对我来说,一个有效的语法应该是:

        auto func = std::bind(&this->virtualFoo, this);

因为取消引用this实际上应该访问vtable并返回一个函数指针。但是c ++ 11并不这么认为。

c++ function pointers virtual derived
1个回答
5
投票

&Abstract::virtualFoo如何返回一个有效的指针,甚至不知道指向实际对象的指针,必须访问一个vtable ???

您已将该函数声明为虚拟。编译器知道该函数是虚拟的。该标准要求通过成员函数指针调用进行虚拟调度。

编译器将必要的信息存储到成员函数指针中以使其发生。注意,成员函数指针不一定仅仅是指向单个地址的指针。它可以包含更多。

编译器实现此目的的确切方式是实现定义。

© www.soinside.com 2019 - 2024. All rights reserved.