【发布时间】:2020-11-10 07:31:28
【问题描述】:
给定:
例子.h
struct Base {
virtual ~Def() = default;
virtual void accept(struct DerivedVisitor* v) = 0;
};
struct Derived : Base {
int num;
void accept(struct DerivedVisitor* v) override;
};
struct DerivedVisitor {
virtual void visit(Derived* d) = 0;
};
Example.cpp
#include "Example.h"
void Derived::accept(struct DerivedVisitor* v) {
v->visit(this);
}
假设我想从“scratch”创建一个 Derived 的实例。由于它包含一个来自 Base 的虚函数,我将如何获取其虚函数表的地址,以便我可以执行以下操作:
main.cpp
#include <iostream>
#include <memory>
#include "Example.h"
struct Visitor : DerivedVisitor {
void visit(Derived* d) override {
std::cout << d->num << std::endl;
}
};
int main() {
int num = 5;
// Create Derived instance from scratch
auto der = malloc(sizeof(Derived));
auto derBytes = static_cast<char*>(der);
new (derBytes) void*(/*HERE I NEED POINTER TO Derived VFT*/); // <------------- How?
new (derBytes + sizeof(Base)) int(num);
// Just to see that it works:
Base* base = reinterpret_cast<Derived*>(der);
Visitor visitor{};
base->accept(&visitor);
free(der);
return 0;
}
这个编译器是特定的吗?如果是这样,如果有人熟悉的话,我正在使用 MinGW。
【问题讨论】:
-
这似乎是一个 XY 问题。虚函数表是一个实现细节,甚至不需要存在于 C++ 实现中。
-
没有充分的理由这样做。你真正想要完成什么?
-
我正在尝试构建一个 LR(1) 解析器,它可以根据其描述解析任何 LR(1) 语法。解析的结果应该存储在 AST 中,它由语法中不同规则的类组成。由于解析器是通用的,它无法知道构成 AST 的具体类,因为这些类是根据语法生成的,因此需要从内存布局描述中构造 AST。一旦内存被正确填满,解析器的调用者就可以在 AST 的顶部节点上执行 reinterpret_cast。无论如何,这就是想法。
-
我想我找到了解决方法。调用者确实知道 AST 的特定类,因此可以将所有指向类的 vtable 的指针作为参数发送给解析器。我在 AST 中使用虚函数,以便在类型检查器/解释器/编译器中使用访问者模式对其进行导航。如果有关于如何更清洁的想法,我将不胜感激。 :) @RemyLebeau
-
你在哪里定义
Def?
标签: c++ memory vtable vptr vmt