Задать вопрос
PavelK
@PavelK

Как получить адрес наследника?

Приветствую!
Есть класс, MyClass, унаследованный от абстрактного класса IInterface
MyClass * myClass = new MyClass(0);
IInterface * interface = myClass;

В распоряжении я имею только адрес interface, больше ничего! т.е. да же заголовочника MyClass, изменять код IInterface или MyClass я не могу.
Как получить из него адрес myClass ?
Если я c делаю:
qDebug()<<"MyClass"<<myClass;
qDebug()<<"Interface"<<interface;

то разумеется адреса отличаются...
нужно как-то через interface получить адрес myClass.
Можно сдвинуть указатель, например на 2 и получить нужный адрес, но это костыль.
P.S. да это реально надо, да уверен.
P.P.S. код для примера. В реальности, имеется только заголовочник IInterface и переменная interface - указатель на него.
  • Вопрос задан
  • 154 просмотра
Подписаться 1 Сложный Комментировать
Решения вопроса 2
@Mercury13
Программист на «си с крестами» и не только
Именно так и делать. Потому что от вас требуется наладить шаблон «Public Морозов» в очень тяжёлых условиях (нет даже заголовка). Так что вам придётся повторять то, что обычно делают компилятор и линкер.

Может помочь устройство таблиц виртуальных методов и dynamic_cast именно в вашем компиляторе. Например, на MinGW у меня получилось вот такое.
#include <iostream>


class A {
public:
    int a;
    virtual void doA() {}
    virtual ~A() = default;
};

// class B, C, D, E  аналогично {

class DE : public D, public E { int de; };
class AB : public A, public B { int ab; };
class CDE : public C, public DE { int cde; };

class All : public AB, public CDE {};


struct Vtable {
    uint32_t d[1];
};

union PObject {
    void* asVoid;
    Vtable** asVtable;
    char* asRaw;
};

int main()
{
    All all;
    All* pAll = &all;
    E* pThis = &all;
    std::cout << pAll << " " << pThis << std::endl;

    PObject pX;
    pX.asVoid = pThis;
    while (true) {
        uint32_t offset = -(*pX.asVtable)->d[-2];
        std::cout << "Got offset " << offset << std::endl;
        if (offset == 0)
            break;
        pX.asRaw -= offset;
        std::cout << "Got pointer " << pX.asVoid << std::endl;
    }

    return 0;
}

До промежуточного потомка (DE или CDE) достучаться не удалось.
Ответ написан
@Kobalt_x
C++ developer
потому что неизвестно каким по счёту vtable будет IInterface у MyClass,
обычно layout такой vtable1/class data...vtablen/class data. Подробнее советую почитать
https://shaharmike.com/cpp/vtable-part2/
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы