@DanyaFantomas

Как восстановить указатель на не первый базовый класс из неизвестного производного класса?

Имеется некоторые классы A, B, C, D, E.
A, B, C из них интерфейсы.
Иерархия наследования такова:
У классов D и E по два родителя
{A, C} -> D, {B, C} -> E.
Так вот. У меня есть функция, в которую передаётся указатель типа void*, но подразумевается что он указывает на объект одного из этих классов. Мне нужно корректно привести этот указатель void* к указателю на класс C. Обычный reinterpret_cast приводит к вылетам программы, когда вызываются методы не первого базового класса, т.е. Если я привёл void* который указывал на класс D, к указателю на C и вызвал один из методов C, то это приводило к вылету, но если приводить к указателю на класс A и вызывать его методы, то всё работает хорошо.
  • Вопрос задан
  • 154 просмотра
Пригласить эксперта
Ответы на вопрос 2
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
#include <stdio.h>

class A
{
public:
        virtual ~A()
        {
        }
};

class B
{
public:
        virtual ~B()
        {
        }
};

class C
{
public:
        virtual void dump() = 0;
        virtual ~C()
        {
        }
};

class D: public A, public C
{
public:
        virtual void dump()
        {
                printf("D: %p\n", this);
        }
};

class E: public B, public C
{
public:
        virtual void dump()
        {
                printf("E: %p\n", this);
        }
};

void f(void *p)
{
        C *pc1 = dynamic_cast<C*>((A*)p);
        C *pc2 = dynamic_cast<C*>((B*)p);
        C *pc3 = dynamic_cast<C*>((C*)p);

        if (pc1)
                pc1->dump();
        else if (pc2)
                pc2->dump();
        else if (pc3)
                pc3->dump();
}

int main()
{       
        D d;
        E e;

        printf("d: %p, e: %p\n", &d, &e);

        A *pa = &d;
        f(pa);

        B *pb = &e;
        f(pb);

        C *pc1 = &d;
        f(pc1);

        C *pc2 = &e;
        f(pc2);

        D *pd = &d;
        f(pd);

        E *pe = &e;
        f(pe);

        return 0;
}
Ответ написан
Комментировать
15432
@15432
Системный программист ^_^
https://angelorohit.blogspot.com/2008/12/casting-w...
Вроде бы не получится сделать

Поставьте первым в наследовании класс С, заведите поле типа, в зависимости от которого определяйте, к D или к E кастовать, после чего уже кастуйте к A или B.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы