2013-05-27 3 views
1

Мне было интересно, если typeid является «достаточно жестким» критерием безопасности типа, чтобы отказаться от всех обычных мер предосторожности. В частности, рассмотрим следующий фрагмент кода:Является ли typeid() достаточным для безопасности типа?

class storage 
{ 
private: 
    std::map<std::type_index, void*> objects; 

public: 
    template<typename T> 
    void put(T* ptr) 
    { 
     objects[typeid(*ptr)] = ptr; 
    } 
}; 

storage stor; 

ClassA* a = new ClassA(); 
ClassB* b = new ClassB(); 

stor.put(a); 
stor.put(b); 

это безопасно, чтобы получить объекты обратно с карты, используя информацию из typeid?

template<typename T> 
T* storage::get() 
{ 
    return static_cast<T*>(objects[typeid(T)]); 
} 

Спасибо, Н.

+0

Поскольку 'ClassA' и' ClassB' могут быть _implicitly_ преобразованы в 'void *', вам не нужно использовать 'static_cast' для хранения их на карте. –

+0

Я хотел прояснить, что такое конверсии, но соответствующим образом отредактировал пример. – nes

+0

Я также отредактировал пример, чтобы указатели сохранялись под их реальным типом 'typeid (* ptr)' для предотвращения проблем с абстрактными базовыми классами. – nes

ответ

1

Он работает, в том смысле, что a2 имеет такое же значение, как a.

Это не обязательно «безопасно». Например, если a указал на экземпляр некоторого производного класса A, то a2 не гарантировалось бы иметь то же значение, что и a. Поэтому безопасность зависит от того, что вы подразумеваете под словом «отказаться от обычных мер предосторожности». Вы не можете отказаться от «меры предосторожности», что если вы конвертируете указатель в void*, вам необходимо его вернуть обратно в исходный.

+0

Я отредактировал этот вопрос, чтобы немного поблизить фактический код интереса. В этой ситуации то, что я помещаю в карту, и что я хочу выбраться, никогда не должно быть разных типов. – nes

Смежные вопросы