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

C++ 从基类实例获取指向(纯)虚函数的指针,c++,function,pointers,virtual,derived,C++,Function,Pointers,Virtual,Derived,我有下面的c++11代码,可以运行,但我希望它会崩溃,甚至无法编译。检索指向纯虚拟成员函数的指针时应返回空指针或无效指针,或者应被编译器阻止。我想了解它为什么有效 我知道还有其他(更好的)方法来编写代码,这是一个理解语法功能的纯理论问题 #include <iostream> #include <functional> class Abstract { public: void foo() { auto func = std::bind(

我有下面的c++11代码,可以运行,但我希望它会崩溃,甚至无法编译。检索指向纯虚拟成员函数的指针时应返回空指针或无效指针,或者应被编译器阻止。我想了解它为什么有效

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

#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;
}
当取消引用
时,此
实际上应该访问vtable并返回函数指针。但是c++11没有这样想

&Abstract::virtualFoo
如何在不知道指向实际对象的指针的情况下返回有效指针,这是访问vtable所必需的

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

编译器将必要的信息存储到成员函数指针中,以实现这一点。请注意,成员函数指针不一定只是指向单个地址的指针。它可以包含更多的内容


编译器实现这一点的确切方式是由实现定义的。

vtable中有一个用于
virtualFoo
的条目,但其值在ABC中为零。如果不使用函数指针,然后调用
func()
您只需调用
virtualFoo()
您将得到相同的输出,我真的不明白为什么您认为这不应该起作用,而
std::bind
在某些情况下是有用的,大多数用例应该使用lambdas。在您的代码中包含此示例。@Botje:是的,但在这种情况下,为什么不传递一个空指针来绑定?@Someprogrammerdude:这纯粹是一个MCVE,我这样做是为了避免直接调用virtualFoo()来通过显式检索指针来说明问题。我当然知道,谢谢。例如,这意味着不可能将它们转换为添加了“This”作为第一个参数的普通函数指针,也不可能将它们转换为uintptr\t。换句话说,这些不是指针类型,而是更复杂的结构。@galinette yes,将“指向cv void或对象或函数的指针”与“指向非静态类成员的指针”区分开来,另请参见和
        auto func = std::bind(&this->virtualFoo, this);