Как предлагают другие ответы здесь, вы не можете использовать reinterpret_cast
таким образом, потому что значение указателя до base
фактически отличается от значения указателя доderived
.Действительный указатель выводится во время выполнения, поэтому вы должны использовать dynamic_cast
.static_cast
не может работать, поскольку вы не знаете во время разработки, через какой промежуточный тип был получен наиболее производный класс (тот, который вы хотите привести) к типу, на который у вас есть указатель.
Реальный вопрос здесь должен быть следующим: во время разработки я знаю, как вычислить указатель derived
из указателя base
.Как избежать штрафа за время выполнения (из dynamic_cast
)?
Честно говоря, я не вижу здесь действительно хорошего варианта, но вариант возможный - сохранить указатель насамый производный тип в константном указателе внутри корневого класса, например:
struct base {
void* const self;
virtual ~base() {}
protected:
base(void* self) : self(self) {}
};
struct derived : public virtual base {
derived() : base(this) {}
}
Это уродливо и опасно, потому что жертвует безопасностью типов для производительности (если вам действительно повезет, вы получите незначительная производительность во время выполнения из него).Но вы сможете reinterpret_cast
ваш base
указатель (self
член типа void*
) в derived
указатель.