Для связанных типов, о которых вы знаете, но компилятор не знает, используйте static_cast
.
Но в вашем случае вы вообще не должны приводить.
Вы пишете, что
Наше хранилище данных хранит указатель на базовый класс (B).Функции выделяют производные указатели (D).
То есть отбрасывает информацию , что не очень хорошая идея.Кто-то понял, что это не очень хорошая идея, что на самом деле это не может работать, и поэтому попытался динамически хранить информацию этого типа в значении B::_some_data
.Общий эффект: выбросить поддержку C ++ для обработки информации о типе и замены очень хрупкого и грязного доморощенного решения.
Чтобы использовать поддержку C ++, сделайте B полиморфнымкласс, то есть, по крайней мере, с одним virtual
членом:
struct B { virtual ~B() {} };
Я удалил элемент данных _some_data
, так как, очевидно, его единственная цель состояла в том, чтобы отслеживать динамический тип, и теперь поддержка C ++ делает этона практике через так называемый «указатель vtable» в объекте.Общий размер объекта, вероятно, одинаков.Однако притяжение клопов и явное уродство уменьшаются на несколько порядков.; -)
Затем,
struct D
: B
{
int some_more_data_;
D( int v ): some_more_data_( v ) {}
};
И затем, с полиморфными классами, ваш код обработки может использовать безопасный dynamic_cast
, как показано ниже:
B* const objB = getOutData();
if( D* const objD = dynamic_cast<D*>( objB ) )
{
// do some processing using objD
}
Теперь эта ручная динамическая проверка типов все еще очень грязная и отражает архитектуру системы без OO.Благодаря объектной ориентации, вместо операций, проверяющих, какие данные им были предоставлены, данные фактически содержат указатели на соответствующие специализированные операции.Но я думаю, что было бы лучше всего делать один шаг за раз, и в качестве первого шага вышеперечисленное: избавиться от хрупкой притягивающей ошибки схемы доморощенной динамической проверки типов и использовать относительно чистую супер-пупер свежую, приятно пахнущую, хорошо выглядящуюПоддержка C ++ для этого.: -)