C++ Как получить указатель на таблицу виртуальных функций класса?

Дано:

Example.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);
}

Скажем, я хотел создать экземпляр 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, если кто-то знаком с ним.

1 ответ

Решение

Это конкретный компилятор?

Да, это зависит от компилятора.

В языке C++ не существует такой вещи, как "таблица виртуальных функций". Такая таблица является деталью реализации.

Учитывая, что такая таблица не существует на языке, также нет возможности получить указатель на таблицу в стандартном C++. Предполагая, что у вашего компилятора есть такая вещь, как виртуальная таблица (что является разумным предположением), возможно, ваш компилятор задокументировал способ доступа к ней. Однако я в этом сомневаюсь. Возможно, вам придется сделать это на языке ассемблера.

Другие вопросы по тегам