c++ - 从基类实例获取指向(纯)虚函数的指针
问题描述
我有以下 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;
}
意图很明确,在基类函数 foo() 中我想获得派生虚函数的指针。
但是,据我了解,它不应该工作,甚至不应该用纯虚函数编译。对于非纯虚函数,它应该执行基类函数。但是,看到它编译并产生预期的输出,我感到非常惊讶:它打印“I am Derived1”然后“I am Derived2”
如何&Abstract::virtualFoo
在不知道指向实际对象的指针的情况下返回有效指针,这是访问 vtable 所必需的???
在线 C++ 链接:https ://onlinegdb.com/SJfku8rvV
对我来说,一个有效的语法应该是:
auto func = std::bind(&this->virtualFoo, this);
因为取消引用this
实际上应该访问 vtable 并返回一个函数指针。但是 c++11 不这么认为。
解决方案
如何
&Abstract::virtualFoo
在不知道指向实际对象的指针的情况下返回有效指针,这是访问 vtable 所必需的???
您已将函数声明为虚拟函数。编译器知道该函数是虚函数。该标准要求通过成员函数指针调用进行虚拟调度。
编译器将必要的信息存储到成员函数指针中以实现这一点。请注意,成员函数指针不一定只是指向单个地址的指针。它可以包含更多。
编译器实现这一点的确切方式是实现定义的。
推荐阅读
- ios - 如何在 SwiftUI 中制作内阴影
- qt - MapCircle 和 MapPolyline 不在 linuxfb 上显示
- firebase - 在 Firebase 实时数据库键中使用重音字符是个好主意吗?
- javascript - 从数组中获取不重复的随机数
- php - PHP:带有 2 个值的 html 下拉列表,其中一个隐藏
- c - 在 Linux 5.4 上以编程方式获取 USB 设备的供应商 ID、产品 ID
- azure - 在 Cloud Shell 中使用 Bash 打开代码编辑器以使用 VS Code 编辑存储在 Azure 中的文件
- google-apps-script - 为 Google 表单选择另一个脚本项目
- json - jq 在新过滤器中包含过滤器的结果
- javascript - <%= yield %>、turbolinks 和 algolia 地方的问题